所以我的手上有一点WTF:双精度数学根据它运行的线程返回不同的结果.
码:
double d = 312554083.518955;
Console.WriteLine(d);
d += 0.1d;
Console.WriteLine(d);
d = 2554083.518955;
Console.WriteLine(d);
d += 0.1d;
Console.WriteLine(d);
Run Code Online (Sandbox Code Playgroud)
这打印:
312554083,518955
312554080
2554083,518955
2554083,5
Run Code Online (Sandbox Code Playgroud)
但如果我在闪亮的新线程上执行它,它会返回:
312554083,518955
312554083,618955
2554083,518955
2554083,618955
Run Code Online (Sandbox Code Playgroud)
(你知道,这是正确的结果)
正如你所看到的,有些东西切断了八位数字,无论是小数还是数字.我在返回错误结果的线程上运行了相当多的本机代码(DirectX(SlimDX),Freetype2,FMOD); 也许他们正在配置FPU来做这件事或者其他什么.但是,这段代码是纯C# - 无论它运行在哪个线程上,它编译的MSIL都是相同的.
以前有人见过这样的东西吗?原因是什么?
Jon*_*eet 10
是的,DirectX确实改变了一些东西 - 它在FPU上设置了一点,以改变它处理算术的方式.这将是问题的原因 - 当然,当处理二进制浮点数时,期望十进制算术给出"准确"结果的正常警告仍然适用.您显示的数字不是首先是双打的确切值.
如果你想避免DirectX改变事情,看看这个问题,特别是Greg的回答:
您可以通过将
D3DCREATE_FPU_PRESERVE标志传递给CreateDevice 来告诉Direct3D不要弄乱FPU精度 .CreateFlags.FpuPreserve如果需要,还有一个与此标志()等效的托管代码.