2017-07-25 3 views
0

Lassen Sie uns sagen, ich habe ein Modul:Parameter Codierung in gfortran Moduldateien

module testParam 

    real, parameter :: x=1.0, xx=10.0 
    real, parameter :: pi=3.14 

end module testParam 

es Kompilieren mit

gfortran -c testParam.f90 

Und schauen Sie in der generierten Moduldatei

cp testparam.mod testparam.gz 
gunzip testparam.gz 

Das getrimmte Ausgangs ist:

(2 'pi' 'testparam' '' 1 ((PARAMETER UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN 
IMPLICIT-SAVE 0 0)() (REAL 4 0 0 0 REAL()) 0 0() (CONSTANT (REAL 4 0 
0 0 REAL()) 0 '[email protected]')() 0()() 0 0) 

4 'x' 'testparam' '' 1 ((PARAMETER UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN 
IMPLICIT-SAVE 0 0)() (REAL 4 0 0 0 REAL()) 0 0() (CONSTANT (REAL 4 0 
0 0 REAL()) 0 '[email protected]')() 0()() 0 0) 

5 'xx' 'testparam' '' 1 ((PARAMETER UNKNOWN-INTENT UNKNOWN-PROC UNKNOWN 
IMPLICIT-SAVE 0 0)() (REAL 4 0 0 0 REAL()) 0 0() (CONSTANT (REAL 4 0 
0 0 REAL()) 0 '[email protected]')() 0()() 0 0) 

Dann können wir sehen, dass der Wert von x als '[email protected]' gespeichert wurde und pi als '[email protected]' und xx als '[email protected]' gespeichert wurde. Wie kann ich den String-codierten Parameter zurück in eine Zahl konvertieren?

Angesichts des Wertes des X-Terminus nahm ich ursprünglich einfach an, für ein Format a @ b, a * 10^b aber der Wert für Pi ist hexadezimal codiert (und für die xx-Variable int (0xa) ==) 10.0 also zumindest ein Teil davon ist hex). Vielleicht ist es eine hexadezimale Fließkommazahl?

+0

Welche Version von gfortran? Obwohl, um ehrlich zu sein, die Art, wie ich es tun würde, ist wahrscheinlich 'testParam verwenden; print *, x; end' usw. – francescalus

+0

5.3.1, würde ich auch, aber ich schreibe etwas Code, der die Mod-Datei parasiert, um herauszufinden, was das Modul macht, ohne es "laufen" zu lassen. – Rob

+1

Es sieht für mich so aus, als würde man die binäre Form eines Gleitkommawertes mit einfacher Genauigkeit mit den etwas zerlegten Bits ablegen. Der Teil zwischen der "0" und das "@" ist eindeutig die Mantisse. Ich könnte vermuten, dass das "@ 1" den Exponenten in irgendeiner Form oder Mode darstellt, aber es wäre klarer mit Zahlen, die einen Exponenten ungleich Null hätten. – Craig

Antwort

0

Mit Hilfe von @roygvib Kommentar dies für Python arbeitet

def hextofloat(s): 
    # Given a hex like parameter '[email protected]' returns 5065465344.0 
    man, exp =s.split('@') 
    exp=int(exp) 
    decimal = man.index('.') 
    man = man[decimal+1:] 
    man = man.ljust(exp,'0') 
    man = man[:exp]+'.'+man[exp:] 
    man = man +'P0' 
    return float.fromhex(man) 

Split den String-Wert in das mantisa (0.12decde) und Exponenten (9), erhalten die Hex-Zahl rechts von der Dezimalstelle (12decde) und füllen Sie es mit genügend Nullen (12decde00), so dass es mindestens so lange wie der Exponent ist, setzen Sie die Dezimalstelle zurück in (12decde00.0) und setzen Sie dann ein 'P0' (12decde00.P0) auf das Ende und gehen Sie zu float.fromhex()

+0

Je nachdem, wie allgemein es sein müsste, würdest du es auch wollen Test mit Inf, NaN und möglicherweise +/- 0 und denormals (die letzten zwei sind vermutlich OK, wie-ist). – Craig