2017-01-21 21 views
0

Ist es möglich, sehr kleine Zahlen in Fortran wie 1E-1200 zu erreichen? Ich weiß, wie man es in Python macht, aber mein Code für Master-Thesis läuft zu langsam. Mein Vorgesetzter empfiehlt mir, Fortran zu verwenden, aber ich bin mir nicht sicher, ob das ein Problem ist.Sehr kleine Zahlen in Fortran

+0

Ich bin ein Fortranner, aber trotzdem würde ich prüfen, ob der Algorithmus schnell genug ist. Das Ändern der Sprache macht keine Wunder, obwohl einige Schleifen in Python langsam sind. –

+3

Hi @ wafelos, Es ist oft der Fall, dass bei Verwendung eines geeigneten Einheitensystems (d. H. Atomeinheiten https://en.wikipedia.org/wiki/Atomic_units) der Bereich der Fließkommazahlen viel enger wird. Es ist wichtig zu wissen, dass die Verwendung von 128 Präzisionstypen Ihre Berechnungen wahrscheinlich verlangsamen wird, da sie nicht von der Hardware unterstützt werden. –

Antwort

0

Die meisten Fortran-Compiler unterstützen das REAL128-Datenformat, das mit IEEE binary128 übereinstimmt. Einige unterstützen auch REAL80 mit ähnlicher Reichweite, passendem C-Long-Double. Diese haben keine Leistung von REAL64, sollten aber viel schneller als Python sein.

+0

C legt nicht fest, welches Format "long double" sein soll, also sind alle anderen Typen. In MSVC ist 'long double' genau dasselbe wie' double'. In Plattformen ohne erweiterte 80-Bit-Genauigkeit kann IEEE-754 doppelte oder vierfache Genauigkeit sein –

1

Die kurze Antwort ist ja.

Moderne Compiler unterstützen typischerweise sogenannte Quad-Präzision, eine 128-Bit-Real. Eine portable Möglichkeit, auf diesen Typ zuzugreifen, ist die Verwendung des ISO_FORTRAN_ENV. Hier ist ein Beispielprogramm zu zeigen, wie groß und klein diese Zahlen erhalten:

program main 
    use ISO_FORTRAN_ENV, only : REAL32, REAL64, REAL128 

    ! -- tiny and huge grab the smallest and largest 
    ! -- representable number of each type 
    write(*,*) 'Range for REAL32: ', tiny(1._REAL32), huge(1._REAL32) 
    write(*,*) 'Range for REAL62: ', tiny(1._REAL64), huge(1._REAL64) 
    write(*,*) 'Range for REAL128: ', tiny(1._REAL128), huge(1._REAL128) 
end program main 

Die Typen REAL32, REAL64 und REAL128 typischerweise bekannt sind als Einzel-, Doppel-, und Quad Präzision. Längere Typen haben einen größeren Bereich von darstellbaren Nummern und größere Präzision.

Auf meinem Rechner mit gfortran 4.8, erhalte ich:

mach5% gfortran types.f90 && ./a.out 
Range for REAL32:  1.17549435E-38 3.40282347E+38 
Range for REAL62:  2.2250738585072014E-308 1.7976931348623157E+308 
Range for REAL128: 3.36210314311209350626E-4932 1.18973149535723176502E+4932 

Wie Sie sehen können, können Quad Präzision Zahlen so klein darstellen als 3.4E-4932.

4

Die vorherigen Antworten, die die Verwendung von REAL128 aus ISO_FORTRAN_ENV vorschlagen, beschreiben eine nicht portable Lösung. Was Sie hier bekommen würden, ist ein realer Typ, dessen Darstellung 128 Bits ist, aber das sagt nichts über die Reichweite oder Genauigkeit des Typs aus! Zum Beispiel haben einige IBM-Systeme eine echte 128-Bit-Art, die tatsächlich zwei Doppelgänger mit einem Offset-Exponenten ist. Dies bringt Ihnen mehr Präzision, aber nicht wesentlich mehr Reichweite.

Der richtige Weg, dies zu tun, ist die intrinsische Funktion SELECTED_REAL_KIND zu verwenden, um die Art der Implementierung zu bestimmen, die den gewünschten Bereich unterstützt. Zum Beispiel:

integer, parameter :: bigreal = SELECTED_REAL_KIND(R=1200) 
real(KIND=bigreal) :: x 

Wenn die Implementierung keine wirkliche Art hat, die einen Wert mit einem Dezimalexponenten von plus oder minus 1200 darstellen kann, erhalten Sie eine Fehlermeldung erhalten, sonst werden Sie die kleinste geeignete erhalten nett.

Sie könnten auch einen P = Wert im Aufruf angeben, um anzugeben, welche Mindestpräzision (in Dezimalziffern) Sie benötigen.

Verwandte Themen