Warum liefert Math.Exp unterschiedliche Ergebnisse zwischen 32-Bit und 64-Bit bei gleicher Eingabe und gleicher Hardware?

Ich verwende .NET 2.0 mit PlatformTarget x64 und x86. Ich gebe Math.Exp die gleiche Eingabenummer und es gibt unterschiedliche Ergebnisse auf beiden Plattformen zurück.

MSDN sagt, dass Sie sich nicht auf ein literales / geparstes Double verlassen können, um die gleiche Anzahl zwischen Plattformen darzustellen, aber ich denke, dass meine Verwendung von Int64BitsToDouble unten dieses Problem vermeidet und die gleiche Eingabe für Math.Exp auf beiden Plattformen garantiert.

Meine Frage ist, warum die Ergebnisse unterschiedlich sind? Ich hätte gedacht, dass:

die Eingabe wird auf dieselbe Weise gespeichert (doppelte / 64-Bit-Genauigkeit)die FPU würde die gleichen Berechnungen durchführen, unabhängig von der Prozessor-Bit-Zahldie Ausgabe wird auf die gleiche Weise gespeichert

Ich weiß, dass ich Gleitkommazahlen nach der 15./17. Ziffer im Allgemeinen nicht vergleichen sollte, aber ich bin verwirrt über die Inkonsistenz hier mit dem, was wie die gleiche Operation auf der gleichen Hardware aussieht.

Weiß jemand, was unter der Haube los ist?

double d = BitConverter.Int64BitsToDouble(-4648784593573222648L); // same as Double.Parse("-0.0068846153846153849") but with no concern about losing digits in conversion
Debug.Assert(d.ToString("G17") == "-0.0068846153846153849"
    && BitConverter.DoubleToInt64Bits(d) == -4648784593573222648L); // true on both 32 & 64 bit

double exp = Math.Exp(d);

Console.WriteLine("{0:G17} = {1}", exp, BitConverter.DoubleToInt64Bits(exp));
// 64-bit: 0.99313902928727449 = 4607120620669726947
// 32-bit: 0.9931390292872746  = 4607120620669726948

Die Ergebnisse sind auf beiden Plattformen konsistent, wenn JIT aktiviert oder deaktiviert ist.

[Bearbeiten

Ich bin mit den unten stehenden Antworten nicht ganz zufrieden. Hier sind einige Details meiner Suche.

http: //www.manicai.net/comp/debugging/fpudiff sagt, dass

32-Bit verwendet die 80-Bit-FPU-Register, 64-Bit die 128-Bit-SSE-Register.

Und der CLI-Standard besagt, dass Doppelte mit höherer Genauigkeit dargestellt werden können, wenn die Hardware dies unterstützt:

[Begründung: Mit diesem Entwurf kann die CLI eine plattformspezifische Hochleistungsdarstellung für Gleitkommazahlen auswählen, bis sie an Speicherorten abgelegt werden. Beispielsweise kann es möglich sein, Gleitkommavariablen in Hardwareregistern zu belassen, die eine höhere Genauigkeit bieten, als ein Benutzer angefordert hat. Gleichzeitig können CIL-Generatoren Operationen durch die Verwendung von Konvertierungsanweisungen zwingen, sprachspezifische Regeln für Repräsentationen zu beachten. Schlussbegründung]

http: //www.ecma-international.org/publications/files/ECMA-ST/Ecma-335.pd (12.1.3 Umgang mit Gleitkomma-Datentypen)

Ich denke, das ist, was hier passiert, weil die Ergebnisse nach Doppels Standard 15 Stellen Genauigkeit unterschiedlich sind. Das 64-Bit-Math.Exp-Ergebnis ist genauer (es hat eine zusätzliche Ziffer), da 64-Bit-.NET intern ein FPU-Register mit höherer Genauigkeit verwendet als das von 32-Bit-.NET verwendete FPU-Register.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage