Fortran Tutorial

Diskussionen zu Tutorials, Änderungs- und Erweiterungswünsche
Antworten
Benutzeravatar
naums
Beiträge: 740
Registriert: Sa Jan 02, 2010 10:40 pm
Kontaktdaten:

Fortran Tutorial

Beitrag von naums » So Jun 28, 2015 7:52 am

Sehr geehrte Lesende sowie Hörende beliebigen sowie keinen oder mehreren Geschlechts,

Ich bastel derzeit an einem Fortran Tutorial. Trotzdem das Tutorial noch etwas Arbeit braucht um als fertig gelten zu können, dürft ihr gerne mal drüberschauen und mir sagen, was doof klingt, etc. Ich habe nämlich das Gefühl, dass ich das Tutorial immer weiter zerstöre, mit später dazugelernten Sachen ...

Zu finden hier: Fortran Tutorial

Ich würde mich über Feedback freuen.

MfG
.globl truth
truth:
mov r0, #42
mov pc, lr

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8858
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Fortran Tutorial

Beitrag von Xin » So Jul 05, 2015 11:06 am

naums hat geschrieben:Ich würde mich über Feedback freuen.
https://www.proggen.org/doku.php?id=fortran:test
Bei Hello World habe ich die Tabs vorne natürlich direkt weggelassen, aber das kann man Dir natürlich nicht anlasten, schließlich hast Du es in Fettschrift über das Listing geschrieben. :-D

Warum eigentlich Tab? Später erklärst Du 6 Leerzeichen und benutzt auch die 6 Leerzeichen statt des Tabs!?

Da ich aber bereits eine Programmiersprache kann, interessiert mich auch ein bisschen, wie dieses Hello World funktioniert. Wofür steht (*,*)? Und warum kommt nicht "Hello World" raus, sondern "<Leerzeichen>Hello World"?

Was bedeutet ähnlich wie der gcc? Kann ich da -std=c++11 eingeben? Funktioniert -Wall?
Ich denke, Du willst auf -o heraus, dann schreib das doch einfach. Andere Flags wüsste ich jetzt nicht, die ähnlich zu C++ sind!?
-I für Include-Verzeichnisse? Wie funktioniert das bei Fortran? Vielleicht könnte man da noch eine kleine Tabelle machen, um da eine Vorstellung zu bekommen, oder den Satz rausnehmen und die Flags anderswo aufführen, da wir ja nur die Installation testen.

Die Seite "Installation machen" und "Installation testen" könnte man zusammenlegen, beides ist ja relativ kurz.

https://www.proggen.org/doku.php?id=fortran:structure
Warum möchtest Du die Fixed Form im Tutorial nutzen? Wir haben 2015, seit Fortran 95 hat man sich mit dem Gedanken angefreundet, dass Lochkarten in der IT wohl keine Zukunft haben.
Ich habe mit Fixed Form kein Problem, da viel Code noch in der Form vorliegt, aber ich würde regelmäßig beides zeigen, so dass die Leute alten Code lesen und warten können und aktuellen Code schreiben können.

https://www.proggen.org/doku.php?id=fortran:variable
"God is real, unless declared integer." ^^

Bei folgendem Programm hat mich interessiert, ob Fortran kommentarlos Integer und Reals verpackt.

Code: Alles auswählen

      PROGRAM main
        INTEGER :: a,b
        REAL :: c,d
 
        a = 12
        b = 42
        c = 0.3
        d = a + b * c
        write (*,*) d
      END PROGRAM
und bekam heraus:

Code: Alles auswählen

xin@trinity:~/temp/fortran$ gfortran vars.f 
xin@trinity:~/temp/fortran$ ./a.out 
   24.6000004    
Pack das doch mal dazu.
Und ich hätte gerne dazu eine Erklärung:

Code: Alles auswählen

xin@trinity:~/temp/fortran$ cat vars.c 
#include <stdio.h>

int main(void)
{
  int a = 12, b=42;
  double c=0.3, d;

  d = a+b*c;
  printf("%.8lf\n", d );

  return 0;
}
xin@trinity:~/temp/fortran$ gcc vars.c 
xin@trinity:~/temp/fortran$ ./a.out 
24.60000000
xin@trinity:~/temp/fortran$ 
Stellen wir die Ergebnisse mal untereinander:

Code: Alles auswählen

24.6000004 (Fortran)
24.60000000 (C)
Wir erinnern uns kurz an das Kapitel "Warum Fortran?"
Außerdem wird Fortran heute noch im mathematischen Sektor verwendet
Da stellt sich mir eine Frage... WARUM!?? Wenn ich das so sehe, sollten wir uns darüber dringend Gedanken machen. ^^


https://www.proggen.org/doku.php?id=fortran:subroutine

"Wichtig bei Fortran ist, dass die Parameter in der Funktion / im Unterprogramm definiert werden. Dort wird entschieden, wie die Werte an den übergebenen Stellen (Call-By-Reference) zu interpretieren sind."

Kapiere ich nicht. Und der "/" macht's nicht einfacher. Es wird später klarer, in dem es erklärt wird. Besser so schreiben, dass die Erklärung vorne steht und der unverständliche Text verschwindet. Die Information Call-by-Reference dann vielleicht nachreichen?

Aktuelles Fortran erlaubt die Typprüfung, soweit mir bekannt.

Code: Alles auswählen

      INTEGER FUNCTION func ( a, b, c )
        INTEGER a,b
        REAL c
        func = a+b * c
        return
      END SUBROUTINE
Subroutine mag mein Compiler nicht. :-)

Nachdem ich das korrigiert habe, kann ich aber immernoch nicht kompilieren:

Code: Alles auswählen

xin@trinity:~/temp/fortran$ cat call.f
      INTEGER FUNCTION func ( a, b, c )
        INTEGER a,b
        REAL c
        func = a+b * c
        return
      END FUNCTION

      PROGRAM main
c        real r

c        r = call func( 12, 42, 0.3 )
c        write (*,*) r
         write (*,*) func( 12, 42, 0.3 )
      END
xin@trinity:~/temp/fortran$ gfortran call.f 
call.f:13.25:

         write (*,*) func( 12, 42, 0.3 )                                
                         1
Error: Return type mismatch of function 'func' at (1) (REAL(4)/INTEGER(4))
Also "REAL FUNCTION func ( a, b, c )".

Weshalb funktioniert die Zuweisung auf r eigentlich nicht?

Aus eigener Erfahrung schreibst Du am besten fertige lauffähige Programme, testest sie und beschreibst sie dann, in dem Du aus dem lauffähigen Programm die Teile rauskopierst. Copy and Paste im Wiki führt zu entsprechenden Fehlern. REAL FUNCTION und END FUNCTION habe ich korrigiert.

Ich lese weiter... :-)
Soweit verstehe ich es aber gut und habe bereits was gelernt. :-)
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
naums
Beiträge: 740
Registriert: Sa Jan 02, 2010 10:40 pm
Kontaktdaten:

Re: Fortran Tutorial

Beitrag von naums » Sa Jul 11, 2015 11:06 pm

Ich würde da gerne wenigstens partiell intervenieren.
Xin hat geschrieben: https://www.proggen.org/doku.php?id=fortran:test
Warum eigentlich Tab? Später erklärst Du 6 Leerzeichen und benutzt auch die 6 Leerzeichen statt des Tabs!?

Da ich aber bereits eine Programmiersprache kann, interessiert mich auch ein bisschen, wie dieses Hello World funktioniert. Wofür steht (*,*)? Und warum kommt nicht "Hello World" raus, sondern "<Leerzeichen>Hello World"?

Was bedeutet ähnlich wie der gcc? Kann ich da -std=c++11 eingeben? Funktioniert -Wall?
Ich denke, Du willst auf -o heraus, dann schreib das doch einfach. Andere Flags wüsste ich jetzt nicht, die ähnlich zu C++ sind!?
-I für Include-Verzeichnisse? Wie funktioniert das bei Fortran? Vielleicht könnte man da noch eine kleine Tabelle machen, um da eine Vorstellung zu bekommen, oder den Satz rausnehmen und die Flags anderswo aufführen, da wir ja nur die Installation testen.

Die Seite "Installation machen" und "Installation testen" könnte man zusammenlegen, beides ist ja relativ kurz.
Die Seiten sind nun zusammengeführt. Wie write funktioniert, und wofür genau die (*,*) stehen, damit beschäftige ich mit im Kapitel Ein- und Ausgabe. Das sollte ich da mal als Verweis hinzufügen. Der Satz mit den ähnlichen Parametern ist erstmal rausgeflogen, evtl. mach ich mal nen Artikel irgendwo über die Verwendung von den GNU-Compilern. Bspw. würden -O gehen, -Wall müsste gehen, -g geht, -D sollte gehen. Selbst Präcompilerdirektiven sollten in Fortran gehen, das habe aber nurnoch am Rand mit Parametern zu tun ;) Includes - dazu komme ich später.
Xin hat geschrieben: https://www.proggen.org/doku.php?id=fortran:structure
Warum möchtest Du die Fixed Form im Tutorial nutzen? Wir haben 2015, seit Fortran 95 hat man sich mit dem Gedanken angefreundet, dass Lochkarten in der IT wohl keine Zukunft haben.
Ich habe mit Fixed Form kein Problem, da viel Code noch in der Form vorliegt, aber ich würde regelmäßig beides zeigen, so dass die Leute alten Code lesen und warten können und aktuellen Code schreiben können.
Guter Vorschlag. Ich muss ehrlich gestehen, das war aus der Faulheit raus geboren, weil ich das halbe Tutorial geschrieben hatte, bis ich gemerkt hatte, dass man auch mit Free Form arbeiten kann.
Xin hat geschrieben: https://www.proggen.org/doku.php?id=fortran:variable

Bei folgendem Programm hat mich interessiert, ob Fortran kommentarlos Integer und Reals verpackt.

Code: Alles auswählen

      PROGRAM main
        INTEGER :: a,b
        REAL :: c,d
 
        a = 12
        b = 42
        c = 0.3
        d = a + b * c
        write (*,*) d
      END PROGRAM
und bekam heraus:

Code: Alles auswählen

xin@trinity:~/temp/fortran$ gfortran vars.f 
xin@trinity:~/temp/fortran$ ./a.out 
   24.6000004    
Pack das doch mal dazu.
Und ich hätte gerne dazu eine Erklärung:

Code: Alles auswählen

xin@trinity:~/temp/fortran$ cat vars.c 
#include <stdio.h>

int main(void)
{
  int a = 12, b=42;
  double c=0.3, d;

  d = a+b*c;
  printf("%.8lf\n", d );

  return 0;
}
xin@trinity:~/temp/fortran$ gcc vars.c 
xin@trinity:~/temp/fortran$ ./a.out 
24.60000000
xin@trinity:~/temp/fortran$ 
Stellen wir die Ergebnisse mal untereinander:

Code: Alles auswählen

24.6000004 (Fortran)
24.60000000 (C)
So kommen wir dazu. Zunächst einmal hast du beim Fortran-Quellcode Reals benutzt, also 32 Bit Fließkommazahlen, und beim C-Code 64 Bit Fließkommazahlen (double). Ich habe den ganzen Spaß bei beiden mal mit 32 Bit durchgerechnet, komme bei beiden auf deine Ergebnisse. Mit 64 Bit Fließkommazahlen ist die Berechnung in Fortran deutlich genauer. Dabei bitte aufpassen, dass der Wert von c folgendermaßen gesetzt wird, damit Fortran wirklich die 64-Bit Zahl benutzt:

Code: Alles auswählen

    REAL*8 c;

    c = 0.3d0;
! alternativ
    c = 0.3_8;
Die Frage wäre aber auch warum bei sowas:

Code: Alles auswählen

#include <iostream>

int main ()
{
    int a, b;
    float c,d;

    a=12;
    b=42;
    c=0.1;
    std::cout << a << b << c << std::endl;
    d=a+b*c;
    std::cout << d << std::endl;
}
Für die Variable c (hier nicht von a und b abgetrennt ausgegeben) genau 0.1 rauskommt und nicht etwa irgendwas abweichendes. In Fortran weicht die ausgegebene Zahl leicht von 0.1 ab.
Xin hat geschrieben: Also "REAL FUNCTION func ( a, b, c )".
ja. weil, die Berechnung einen Real zurückwirft, aber der Rückgabewert (und damit der Datentyp für die "Variable" func) ein Integer ist. Aus dem Grund funktioniert auch die Zuweisung auf r nicht. Weil ebenfalls im Rückgabewert der Funktion ein Real-Wert auf einen Integer-Speicherplatz trifft.
.globl truth
truth:
mov r0, #42
mov pc, lr

Benutzeravatar
naums
Beiträge: 740
Registriert: Sa Jan 02, 2010 10:40 pm
Kontaktdaten:

Re: Fortran Tutorial

Beitrag von naums » Fr Jul 17, 2015 5:54 pm

Hinzufügung: Ich habe festgestellt, dass C-Code (mit einem C-Compiler übersetzt) etwa die gleichen Rundungsfehler verursacht wie der Fortran-Code. Evtl. tut C++ da im Hintergrund böse Magie-Sachen?
.globl truth
truth:
mov r0, #42
mov pc, lr

nufan
Wiki-Moderator
Beiträge: 2557
Registriert: Sa Jul 05, 2008 3:21 pm

Re: Fortran Tutorial

Beitrag von nufan » Fr Jul 17, 2015 7:26 pm

naums hat geschrieben:Hinzufügung: Ich habe festgestellt, dass C-Code (mit einem C-Compiler übersetzt) etwa die gleichen Rundungsfehler verursacht wie der Fortran-Code. Evtl. tut C++ da im Hintergrund böse Magie-Sachen?
Mich interessiert das sehr, aber ich komm da grad nicht mit welche Codestücke du genau vergleichst. Kannst du die bitte nochmals mit deinem Ergebnis posten?

Benutzeravatar
naums
Beiträge: 740
Registriert: Sa Jan 02, 2010 10:40 pm
Kontaktdaten:

Re: Fortran Tutorial

Beitrag von naums » Fr Jul 17, 2015 8:05 pm

Ahoi,

Fortran:

Code: Alles auswählen

     
      PROGRAM main
        INTEGER :: a,b
        REAL :: c,d

        a = 12
        b = 42
        c = 0.3
        d = a + b * c
        write (*,"(F13.10)") d
      END PROGRAM
C-Code:

Code: Alles auswählen

#include <stdio.h>

int main(void)
{
  int a = 12, b=42;
  float c=0.3, d;

  d = a+b*c;
  printf ("%f\n", c);
  printf("%13.10f\n", d );

  return 0;
}

Die Ergebnisse (testf => Fortran, testc => C)

Code: Alles auswählen

[naums@gate fortran]$ ./testf
24.6000003815
[naums@gate fortran]$ ./testc
0.300000
24.6000003815
[naums@gate fortran]$ 
Siehe da, die gleichen Ergebnisse herbeigezaubert. :)

Berichtigung: Den C-Code mit nem C++ Compiler übersetzt bringt die gleicen Ergebnisse.

MfG
.globl truth
truth:
mov r0, #42
mov pc, lr

Antworten