不同CPU上sin的不同值

时间:2013-08-05 14:06:23

标签: c++ sin

我正在编写一个用于计算几何变换的应用程序,当我测试程序时,我发现了一些奇怪的东西:我在两台不同的机器上启动了测试,Z400工作站配备了英特尔®至强®处理器W3550和Z800工作站使用英特尔®至强®处理器X5560,我在一次操作中获得了不同的结果:

double x = 24.169408798217777 * sin(0.59420877837561048) / sin(0.97658754841928608)

使用Z400我得到x=16.330508228047432

Z800抛出此值x=16.330508228047435

最后一位数的值不同,我用该值进行了很多计算,因此结果不方便。

我尝试使用sinl以获得更多精确度,但每个工作站的所有时间都得到相同的值。它出什么问题了?我怎么解决它?

2 个答案:

答案 0 :(得分:2)

2个计算的结果相差1个十进制数字,如下所示,1个二进制数字如下所示。 Z400更接近正确的答案。 sin()计算没有义务精确到最后一个二进制位,而是在1位以内。好的sin()实现对最后一位是正确的**。你的Z800不太好。

printf("%a\n", 16.330508228047432);
printf("%a\n", 16.330508228047435);
printf("%a\n", 24.169408798217777 * sin(0.59420877837561048) / sin(0.97658754841928608));  // my PC eclipse

0x1.0549c2fee85cbp + 4
0x1.0549c2fee85ccp + 4
0x1.0549c2fee85cbp + 4

**准确度要求不是C ++要求,而是IEEE浮点要求。 Trig函数s / b精确到1 ulp(单位最后一个位置)。 好的 trig库在0.5 ulp内是准确的(单位最后一位) - 最好的答案。

答案 1 :(得分:1)

作为猜测,我将建议这与某些处理器计算80位寄存器(而不是64位)中的浮点值有关,并且只会尽可能晚地降低精度。

在GCC上,您可以使用-ffloat-store禁用此功能(这将导致所有数学运算以64位完成,并且还可能导致它稍慢)。

如果80位寄存器是实际问题,this answer还有一些额外的建议也可以提供帮助。