2017-06-13 1 views
2

In Go ich eine typisierte float konstant wie diese erklären können:Wie kann ich eine Float-typisierte Go-Konstante eines beliebigen Bitmusters deklarieren?

const foo float64 = 1e100 

oder eine Variable vom Typ float willkürlicher Bitmuster wie folgt aus:

var bar = math.Float64frombits(0x7ff8c0c0ac0ffee1) 

Aber das ist ein Fehler ("const initializer ... ist keine Konstante "):

const baz = math.Float64frombits(0x7ff8c0c0ac0ffee1) 

Wie könnte ich einen typisierten Float const eines beliebigen Bitmusters deklarieren?

+0

Sie können es speichern als 'uint64' konstant und wandeln sie auf Nachfrage (das ist, wie das mathematische Paket tut es intern) – JimB

+0

Das ist eigentlich ein guter Vorschlag. Es ist ein wenig ärgerlich für exportierte Werte (z. B. solche, die als Sentinel-Werte verwendet werden), da das abhängige Paket auch "math" importieren müsste, aber zumindest sorgt es für Konstanz. – cpcallen

Antwort

2

Ihr Aufruf an Math.Float64frombits tritt zur Laufzeit auf, nicht zur Kompilierzeit und ist daher nicht konstant. Von der effektiven Go-Seite (die es besser erklären wird, als ich kann):

Konstanten in Go sind nur so konstant. Sie werden beim Kompilieren Mal erstellt, auch wenn sie als Locals in Funktionen definiert sind, und können nur Nummern, Strings oder Booleans sein. Aufgrund der Kompilierungszeitbeschränkung müssen die Ausdrücke, die sie definieren, konstante Ausdrücke sein, , die vom Compiler auswertbar sind. Zum Beispiel ist 1 < < 3 eine Konstante Ausdruck, während Math.Sin (math.Pi/4) ist nicht, weil der Funktionsaufruf zu math.Sin zur Laufzeit auftreten muss.

-Link: https://golang.org/doc/effective_go.html#constants

+0

Ich verstehe das. Aber es beantwortet die Frage nicht. (Ich denke, die Antwort auf die Frage könnte sein "sende einen Antrag auf Änderung der Sprache", aber ich möchte sicherstellen, dass ich etwas nicht übersehen habe, bevor ich das tue.) – cpcallen

1

Sie nicht eine Funktion wie Float64frombits in einer konstanten Erklärung nennen kann; Der Funktionsaufruf bedeutet, dass er zur Kompilierzeit nicht vollständig ausgewertet werden kann und daher nicht als Konstante verwendet werden kann. Sie können jedoch nur Bits Dump in einen Float-Wert:

const myFloat float64 = 0x7ff8c0c0ac0ffee1 

func main() { 
    fmt.Println(myFloat) 
} 
+1

Das gilt nicht für die bitweise Darstellung der float64 im Wesentlichen 'float64 (0x7ff8c0c0ac0ffee1)' – JimB

+0

Ja, das ist richtig. Die Frage war nicht spezifisch für die Details dessen, was sie als Ausgabe von der Eingabe erwarteten, daher gab ich die einzige verfügbare Option zum Setzen eines const-Wertes von einem beliebigen Hex-Wert. – Adrian

+1

Die Frage gibt Ergebnisse an, die äquivalent zu 'Float64frombits' sind. Die numerische Konvertierung eines beliebigen Hexadezimalwerts in float64 ist nicht dasselbe wie die Interpretation der Uint64-Bits als float64. – JimB

3

Wenn Sie den Bit-Wert gespeichert werden soll (die im Wesentlichen ein uint64) und haben es als ein float64 auf externe Pakete verfügbar sind, können Sie zur Verfügung stellen eine "konstante" Funktion, die garantiert, dass nur der konstante Wert zurückgegeben wird. Genau so funktionieren Funktionen wie math.NaN.

const uintFoo = 0x7ff8c0c0ac0ffee1 

func ConstFoo() float64 { 
    return math.Float64frombits(uintFoo) 
} 
Verwandte Themen