在特殊情况下双打失去数字(无int转换)

cct*_*tsm 4 c#

所以我的手上有一点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如果需要,还有一个与此标志()等效的托管代码.