2016-07-16 23 views
1

Im Jahr 2013 gab es eine Frage zum Umwandeln eines großen Arbeitscodes von doppelter in vierfache Genauigkeit: "Converting a working code from double-precision to quadruple-precision: How to read quadruple-precision numbers in FORTRAN from an input file", und der Konsens bestand darin, Variablen mit einem einstellbaren Parameter "WP" zu deklarieren, der die "Arbeitsgenauigkeit" angibt, anstatt a separate Version des Programms mit Variablen deklariert mit D + 01, und eine andere Version mit Q + 01. Auf diese Weise können wir ganz einfach hin und her wechseln, indem wir oben WP = real128 oder WP = real64 definieren, und der Rest muss nicht geändert werden.Wie kann ich die Genauigkeit einer Zahl als einstellbaren Parameter deklarieren?

Aber wie machen wir das?

habe ich versucht, den Vorschlag in der Antwort auf diese Frage, indem Sie einen einfachen Code TEST.F90 machen:

PROGRAM TEST 
    use ISO_FORTRAN_ENV 
    WP= real128 
    IMPLICIT NONE 
    real (WP) :: X 
    X= 5.4857990945E-4_WP 
    END PROGRAM TEST 

mit kompiliert:

~/gcc-4.6/bin/gfortran -o tst.x TEST.F90 

Aber es gibt:

 IMPLICIT NONE 
        1 
Error: Unexpected IMPLICIT NONE statement at (1) 
QLEVEL16.F90:5.12: 

     real (WP) :: MEL 
      1 
Error: Parameter 'wp' at (1) has not been declared or is a variable, which does not reduce to a constant expression 
QLEVEL16.F90:6.29: 

     MEL= 5.4857990945E-4_WP 
          1 
Error: Missing kind-parameter at (1) 

Antwort

4

Der Typbezeichner muss ein Integer-Parameter sein - und Sie deklarieren ihn nicht entsprechend. Außerdem muss implicit none vor jeder Deklaration gehen.

Hier ist eine Arbeitsversion, beide Aspekte ein:

PROGRAM TEST 
    use ISO_FORTRAN_ENV 
    IMPLICIT NONE 
    integer, parameter :: WP= real128 
    real (WP) :: X 

    X= 5.4857990945E-4_WP 
END PROGRAM TEST 
+0

Ausgezeichnet! Die Antwort in dem anderen Thread ließ es so aussehen, als ob WP = real128 gleich nach der Verwendung von ISO_FORTRAN_ENV sein sollte, und zeigte nicht den "integer, parameter ::" Teil. Das war die Ursache meines Problems. Vielen Dank! – user1271772

+3

Es ist vielleicht verlockender zu verwenden, intrinsisch :: iso_fortran_env, wp => real128', nein? – francescalus

+0

Danke @francescalus. Was sind die Vor- und Nachteile der beiden alternativen Möglichkeiten? – user1271772

0

Eigentlich viele Code mit dieser WP-Ansatz. Viele mit ausgewählter _ * _ Art intrinsischer Funktion. Aber ich denke, es gibt einen "leichteren" Weg. Es wird die Standardpräzision verwendet, ohne ein beliebiges Schlüsselwort anzugeben und mithilfe des Compiler-Flags die Standardpräzision auszuwählen.

Pro ist diese Methode einfacher, wenn Sie keine genaue Kontrolle der Genauigkeit für jede Variable benötigen. Con ist das wird stark abhängig von Compiler-Flags, die für jeden Compiler variiert oder sogar nicht verfügbar ist.

Für gfortran gibt es weitere Flags -freal4-real8 oder -freal4-real16, um jede explizit angegebene Variable mit niedrigerer Genauigkeit zu höherer Genauigkeit zu fördern.

+0

Dies ist eigentlich der bevorzugte Ansatz, denke ich. Aber ich weiß nicht, wie ich es machen soll. – user1271772