MSDN说你不能依赖于一个文字/解析的Double来表示平台之间的相同数量,但是我认为我使用Int64BitsToDouble可以避免这个问题,并保证在两个平台上对Math.Exp的输入相同.
我的问题是为什么结果不一样?我会以为:
>输入以相同的方式存储(双精度/ 64位精度)
> FPU将进行相同的计算,而不管处理器的位数如何
>输出以相同的方式存储
我知道我不应该比较15/17位数之后的浮点数,但是我在这里与在同一个硬件上看起来像是一样的操作感到困惑.
任何人都知道发生什么事情?
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
JIT打开或关闭的两个平台上的结果是一致的.
[编辑]
我不完全满意下面的答案,所以这里有一些更多的细节从我的搜索.
http://www.manicai.net/comp/debugging/fpudiff/说:
So 32-bit is using the 80-bit FPU registers,64-bit is using the 128-bit SSE registers.
而CLI标准表示,如果硬件支持双精度可以用更高的精度表示:
[Rationale: This design allows the CLI to choose a platform-specific high-performance representation for
floating-point numbers until they are placed in storage locations. For example,it might be able to leave
floating-point variables in hardware registers that provide more precision than a user has requested. At the
Partition I 69
same time,CIL generators can force operations to respect language-specific rules for representations through
the use of conversion instructions. end rationale]
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-335.pdf(12.1.3处理浮点数据类型)
我认为这是这里发生的一切,因为Double的标准精度为15位,结果不同. 64位Math.Exp结果更精确(它有一个额外的数字),因为内部的64位.NET正在使用比32位.NET使用的FPU寄存器更精确的FPU寄存器.