问题。
Microsoft Visual C++ 2005 编译器,32 位 windows xp sp3,amd 64 x2 cpu。
代码:
double a = 3015.0;
double b = 0.00025298219406977296;
//*((unsigned __int64*)(&a)) == 0x40a78e0000000000
//*((unsigned __int64*)(&b)) == 0x3f30945640000000
double f = a/b;//3015/0.00025298219406977296;
计算的结果(即“f”)是 11917835.000000000 ( ((unsigned __int64 )(&f)) == 0x4166bb4160000000) 虽然它应该是 11917834.814763514 (即((unsigned __int64 )(&f)) == 0x4166bb415a128a)
即小数部分丢失。
不幸的是,我需要小数部分才能正确。
问题:
1)为什么会发生这种情况?
2)我该如何解决这个问题?
附加信息:
0)结果直接来自“观察”窗口(没有打印,我没有忘记设置打印精度)。我还提供了浮点变量的十六进制转储,所以我对计算结果非常确定。
1) f = a/b的反汇编为:
fld qword ptr [a]
fdiv qword ptr [b]
fstp qword ptr [f]
2) f = 3015/0.00025298219406977296;产生正确的结果(f == 11917834.814763514 , ((unsigned __int64 )(&f)) == 0x4166bb415a128aef ),但看起来在这种情况下,结果只是在编译时计算:
fld qword ptr [__real@4166bb415a128aef (828EA0h)]
fstp qword ptr [f]
那么,我该如何解决这个问题呢?
PS我找到了一个临时解决方法(我只需要除法的小数部分,所以我现在只使用 f = fmod(a/b)/b ),但我仍然想知道如何正确解决这个问题 -双精度应该是 16 位十进制数字,所以这样的计算不应该引起问题。