2012-04-09 9 views
3

Ich habe ein Fortran-Code in gfortran kompiliert werden (mehrere tausend Zeilen so werde ich versuchen, die wichtigen Linien zu schreiben), das gibt mir:Fortran: Mögliche Wertänderung

nrev(isat)=dint((t_ref-t_in)/zper)+1 
      1 
Warning:Possible change of value in conversion from REAL(8) to INTEGER(4) at (1) 

Sie werden als initialisiert:

integer*4 nrev(nmaxsat) 
integer*4 isat 
real*8  t_ref 
real*8  t_in 
real*8  zper 

Irgendwelche Ideen, wie Sie das beheben können? Danke!

+0

Was möchten Sie genau beheben? Abhängig von der Größe des Ausdrucks mit doppelter Genauigkeit ist er nicht als 32-Bit-Ganzzahl mit Vorzeichen darstellbar. Was erwartest du zu passieren? – talonmies

+0

Wenn ich das volle Programm laufen lasse, sind alle Ausgabewerte NaN, also bin ich besorgt Warnungen wie dieses sind das Problem. Ich habe keine Fehler beim Kompilieren in Gfortran, aber es kompiliert und läuft korrekt, wenn in G77 kompiliert. Ich habe mehrere dieser Warnungen, aber ich konzentriere mich auf diesen, in der Hoffnung, wenn ich Hilfe mit einem bekommen kann, kann ich den Rest herausfinden. –

+0

Wenn Sie NaN-Werte erhalten, bedeutet das, dass Sie irgendwo eine ungültige Fließkommaberechnung haben. Der Code, den Sie angezeigt haben, berechnet einen ganzzahligen Wert. Es ist unmöglich zu sagen, wie die beiden basierend auf dem, was Sie gepostet haben, verwandt sein könnten. – talonmies

Antwort

4

Es ist eine ausgezeichnete Idee, alle Warnungen loszuwerden, sogar kleine - auch wenn nur, wenn Sie mehr signifikante Probleme bekommen, Sie sehen, anstatt die Ausgabe von kleinen Dingen überschwemmt.

In diesem Fall ist die Warnmeldung ziemlich klar; Sie weisen einer Ganzzahl ein Double zu. Die dint Eigenschaft schneidet zwar ab, konvertiert aber keine Typen; Sie weisen also einen Wert mit doppelter Genauigkeit zu, dessen Wert auf eine ganze Zahl gekürzt wurde. Sie können richtig feststellen, dass die intrinsische ist verwirrend benannt, aber ...

Wenn Sie die Konvertierung sowie die Trunkierung, idint tatsächlich konvertiert in eine ganze Zahl.

So zum Beispiel das Programm

program foo 

    integer :: nrev 
    double precision :: t_ref 

    t_ref = 1. 

    nrev = dint(t_ref) 

end program foo 

die gleiche Warnung erzeugt:

$ gfortran -o foo foo.f90 -Wall -std=f95 
foo.f90:8.11: 

    nrev = dint(t_ref) 
      1 
Warning: Possible change of value in conversion from REAL(8) to INTEGER(4) at (1) 

Aber dieses ist in Ordnung:

program foo 

    integer :: nrev 
    double precision :: t_ref 

    t_ref = 1. 

    nrev = idint(t_ref) 

end program foo 

wie wir sehen:

$ gfortran -o foo foo.f90 -Wall -std=f95 
$ 
+6

Anstatt die spezifische intrinsische "idint" zu verwenden, können Sie den generischen Namen "int" verwenden. Mit dem generischen Code ermittelt der Compiler automatisch, welche Funktion vom Argumenttyp verwendet wird, und der Programmierer muss sich nicht an den Namen erinnern. (Es gibt auch ein zweites Argument, in dem Sie den Typ der von der Funktion zurückgegebenen Ganzzahl angeben können.) –

+0

Vielen Dank für diese Erklärung! Dies wird mir helfen, diesen Code viel aufzuräumen und ihn viel besser laufen zu lassen. Ich fragte dies in einem obigen Kommentar, aber können Sie erklären, was der Unterschied zwischen "Mögliche Wertänderung in Konvertierung" und die "Typenkonflikt in Argument" Warnungen ist? Sie scheinen mir auf zwei verschiedene Arten dasselbe zu sagen ... Nochmals vielen Dank! –