2010-12-12 6 views
1

Wenn ich einen Skalar INTEGER, s, und übergeben Sie es an eine Subroutine, wird sein Wert in eine Float konvertiert und ist schrecklich ungenau. Zum Beispiel, wenn ich s = 2 und CALL print_my_int (s), wo es schreiben wird (,) es auf die Konsole, wird es Wert als 2.80259693E-45 angezeigt. Andere skalare Ganzzahlen verhalten sich ähnlich, außer in dem Fall, dass s = 0, in welchem ​​Fall die Ausgabe 0,0000000 ist. Aber auch das ist immer noch falsch, denn eine ganze Zahl sollte offensichtlich keine Dezimalzahl und keine Mantisse anzeigen. Dies ist KEIN Ausgabeformat, da ich andere Ganzzahlen korrekt anzeigen kann, wenn sie lokal angezeigt werden.Hilfe! Übergeben FORTRAN-Ganzzahlen verwandelt sie in ungenaue schwimmt?

Irgendwelche Hinweise, was hier passiert? Muss ich den Argument-Datentyp in der Subroutinen-Definition erzwingen? Kann das überhaupt gemacht werden?

Beispielcode:

PROGRAM print_int 
    INTEGER s 
    s = 2 
    CALL print_my_int(s) 
END PROGRAM print_int 

SUBROUTINE print_my_int(x) 
    WRITE(*,*) x 
END SUBROUTINE print_my_int 

resultierende Ausgabe:

2.80259693E-45 

Antwort

1

Okay, vorzeitige Post, aber ich werde es für jeden überlassen, die in das gleiche läuft. Ich bin nicht mit der Syntax zum Erzwingen von Parametertypen in FORTRAN vertraut. In der Unterprogrammdefinition befindet sich der Datentyp des Parameters unterhalb der Namen- und Parameterliste. Wenn nicht enthalten, warnt der GNU-Compiler nicht oder quietscht. Ich stelle mir vor, dass es standardmäßig in einen anderen Typ umgewandelt wird. So sollte mein obigen Beispiel wie folgt lesen ...

PROGRAM print_int 
    INTEGER s 
    s = 2 
    CALL print_my_int(s) 
END PROGRAM print_int 

SUBROUTINE print_my_int(x) 
    INTEGER x 
    WRITE(*,*) x 
END SUBROUTINE print_my_int 
+1

Es hätte auch funktioniert, wenn Sie den Parameternamen von 'x' in' i' oder 'j' geändert haben, da FORTRAN Typinterferenzen basierend auf den Anfangsbuchstaben der Variablennamen hat. Aber mach das nicht - es ist eine schlechte Übung. – JasonFruit

+0

Danke, mein Herr. Ein praktischer Tipp, aber ich werde darauf achten, das Fehlverhalten zu vermeiden. –

+3

Es ist gut, die Anweisung "implicit none" am Anfang jedes Programms/Unterprogramms zu verwenden, wenn Sie den Compiler bei nicht deklarierten Variablen ersticken wollen. – steabert

2

nichts Neues, nur wollte die Verwendung einer Schnittstelle darauf hinzuweisen, durch einen Code bereitzustellen, die nicht in einem Kommentar paßten:

wie bereits erwähnen Sie implicit none überall am Anfang des Deklarationsteils setzen können, oder alternativ können Sie eine Schnittstelle in Ihrem Programm setzen, die das Unterprogramm verwendet, dann wird der Compiler einen Typenkonfliktfehler werfen:

PROGRAM print_int 
INTERFACE 
    SUBROUTINE print_my_int(x) 
    END SUBROUTINE 
END INTERFACE 
INTEGER s 
s = 2 
CALL print_my_int(s) 
END PROGRAM print_int 

SUBROUTINE print_my_int(x) 
WRITE(*,*) x 
END SUBROUTINE print_my_int 
3

ein weiterer erweiterter Kommentar , einfacher noch als @steabert ‚S:

PROGRAM print_int 
    INTEGER s 
    s = 2 
    CALL print_my_int(s) 

CONTAINS 

SUBROUTINE print_my_int(x) 
    WRITE(*,*) x 
END SUBROUTINE print_my_int 

END PROGRAM print_int 

durch das Unterprogramm im Programm enthalten Sie die Compiler in der Herstellung eine explizite Schnittstelle, Speicher 3 Zeilen Code zwingen. Indem die Deklaration von x innerhalb der Subroutine implizit belassen wird, erkennt der Compiler den Fehler.