2013-03-13 16 views
2

我在我的C具有双值++代码:FPU命令FLD1启动转换双长一倍ST0

double inch = 25.399999618530273; 

当在计算中使用,它是使用加载到FPU ST0寄存器

fldl -0x90(%ebp) 

我可以看到在-0x90(%ebp)下的双精度值是正确的。然而FLD1启动后,它显示为长双值25.3999996185302734375在ST0寄存器,即使我编译-mpc64 -mfpmath = 387和手动设置FPU立即计算和FLD1启动命令之前,双精度:

fpu_control_t cw; 
_FPU_GETCW(cw); 
cw &= ~_FPU_EXTENDED; 
cw |= _FPU_DOUBLE; 
_FPU_SETCW(cw); 

你可以请解释为什么在_FPU_DOUBLE模式下FPU寄存器仍处于扩展精度模式,以及如何解决这个问题?

或者它只是出现只要双(我在Eclipse CDT中查看寄存器),但实际上在内部没有这些额外的数字操作?

+0

我不得不承认,我还没有读过“每位程序员应该知道什么浮点算术”的圣经。 – queen3 2013-03-13 13:35:10

回答

2

编译程序时,您的数字会转换为25.3999996185302734375,因为这是最接近25.399999618530273的double值(使用IEEE-754 64位二进制浮点数)。将double转换为long double没有错误。

当你说你可以看到“double at -0x90(%ebp)”是正确的值,那么,如果你没有看到25.3999996185302734375,你没有看到在那个位置的实际值 - 你所使用的工具使用观察值显示它不准确。

如果您预计double完全代表25.399999618530273,那么您会感到失望;它不,并且您必须设计您的代码以允许这样做,或者使用double以外的其他值表示这样的数字。

你用什么工具测量精度为.000000000000001英寸的长度?这是一个非常优秀的尺子,带有非常棒的放大镜和机器人增强的眼睛?

+0

25.3999996185302734375在Windows VS2010和Eclipse CDT监视窗口中显示为25.399999618530273。我有点困惑,他们都在这里显示不正确的双重价值。 Eclipse显示25.3999996185302734375L为25.3999996185302734375这就是为什么我认为它是长双倍和25.399999618530273是双倍。 – queen3 2013-03-13 14:08:56

+1

@ queen3:25.3999996185302734375十六进制正好是0x19.66666;它适合于“双”。十六进制中的25.399999618530273大约为0x19.66665FFFFFFFE0798CA9EB295A3085。它不能用'double'来表示,因为这些位不合适;一个“double”的有效位只有53位。如果某些软件告诉你一个“double”包含25.399999618530273,那么它就是在撒谎。 – 2013-03-13 14:23:15

+0

Hm,那么在Windows/Linux调试器中验证实际float/double值的正确方法是什么? – queen3 2013-03-13 14:24:41