2016-09-07 2 views
0

Sind diese beiden C# -Methoden vollständig deterministisch - da sie auf allen Plattformen dasselbe Ergebnis liefern?Sind diese beiden Methoden deterministisch?

Fix64 ist struct, die rawValue Feld des Typs long hat. ONE ist eine Konstante, wie diese

Funktion const long ONE = 1L << 32;

1 definiert:

public static explicit operator Fix64(double value) { 
      return new Fix64((long)(value * ONE)); 
     } 

Fix64 Konstruktor, der nur in einem long Wert annimmt weist sie rawValue Feld. Operation in Frage ist hier die Multiplikation. ONE wird in double konvertiert. Dann werden zwei double Werte multipliziert. Dies kann gemäß C# -Spezifikationen mit höherer Genauigkeit geschehen. Das Ergebnis wird dann durch long Cast abgeschnitten. Gibt es eine Chance, dass das niedrigstwertige Bit des resultierenden Werts long unterschiedlich ist, wenn für die Multiplikation auf verschiedenen Plattformen unterschiedliche Genauigkeit verwendet wird? Oder ist diese Methode vollständig deterministisch?

Funktion 2:

public static explicit operator double(Fix64 value) { 
     return (double)value.rawValue/ONE; 
    } 

Dies ist zum ersten Beispiel ähnlich. Genau hier haben wir Division Operation zwischen double s und dass wir Ergebnis als double zurückgeben. Ist es möglich, dass, wenn wir das Ergebnis dieser Methode mit einem anderen double vergleichen, der Compiler während dieses Vergleichs die resultierende double in höherer Genauigkeit hinterlassen kann?

Würde eine andere Besetzung sicherstellen, dass dieser Vergleich immer deterministisch sein wird?

(double)((double)value.rawValue/ONE)

EDIT: Diese beiden Funktionen konvertieren zwischen FixedPoint64 Typ und Doppeltyp. Das Argument hier ist, dass wir nur Einzeloperation verwenden, wir verwenden keinen erweiterten Zwischen-Fließkommawert für zusätzlichen Betrieb. Wenn man also das Ergebnis sofort auf die Standardpräzision kürzt, soll die Berechnung deterministisch sein. Oder gibt es irgendwelche Fehler in dieser Logik?

+0

Mögliches Duplikat von [Ist Fließkomma-Mathematik in C# konsistent? Kann es sein?] (Http://stackoverflow.com/questions/6683059/is-floating-point-math-consistent-in-c-can-it-be) – Sinatr

+0

Sicher kennen Sie bereits die Antwort. Der grundlegende Fehler, den Sie machen, geht davon aus, dass es etwas mit dem von Ihnen verwendeten Ausdruck zu tun hat.Das ist nicht korrekt, Sie können nicht davon ausgehen, dass das Argument * value * konsistent ist. –

+0

@HansPassant Ich verstehe nicht, was du meinst. Gibt es für beide Funktionen eine Antwort? Ich muss doppelte Werte in Fix64-Struktur und zurück zu doppelten Werten mehrfach konvertieren. Ich muss wissen, ob diese Konvertierungen auf verschiedenen Plattformen zu denselben Ergebnissen führen oder ob sie behoben werden müssen. Ich habe Argumente gelesen, dass Determinismusprobleme nur in Zwischenergebnissen über mehrere Operationen aufgrund der erweiterten FPU-Genauigkeit und möglicherweise in Implementierungen transzendenter Funktionen auftreten, aber nicht für einzelne Berechnungen, die wie in der ersten Funktion sofort abgeschnitten werden. – zigzag

Antwort

0

Die Antwort ist ja, beide sind deterministisch. Erklärung, die ich davon bekam, ist vom Autor der Bibliothek ist:

Für Multiplikation/Division, wenn eine der FP-Zahlen ist Macht der zwei Zahl (2^x), wird signifikante/Mantisse während der Berechnung nicht ändern. Nur der Exponent ändert sich (der Punkt wird verschoben). Eine Rundung wird also niemals passieren. Das Ergebnis wird deterministisch sein.

Beispiel: Eine Zahl wie 2^32 wird dargestellt als (Exponent: 32, Mantisse: 1). Wenn wir das mit einem anderen Gleitkomma (exp, man) multiplizieren, ist das Ergebnis (exp + 32, man * 1). Für die Division ist das Ergebnis (expo - 32, man * 1). Das Multiplizieren der Mantisse mit 1 ändert nicht die Mantisse, es ist also egal, wie viele Bits es hat.

Verwandte Themen