在Delphi XE2中使用double类型时,我得到的计算结果无效。下面是一个非常简单的计算代码,应该导致零。相反,它返回-1.13686837721616E-13,这是不正确的。
var
dblValue1, dblValue2, dblValue3, dblTotal: double;
begin
try
dblValue1 := 1671.37;
dblValue2 := 871.37;
dblValue3 := 800.00;
dblTotal := (dblValue1 - dblValue3);
dblTotal := (dblTotal - dblValue2);
Write(FloatToStr(dblTotal));
ReadLn;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
无论是32位还是64位,都会以同样的方式失败。
为什么这个计算会失败?
答案 0 :(得分:2)
它不会失败 - 您只是遇到计算机上任何浮点运算表示中固有的精度限制。为了比较,我只是在交互式Python shell中尝试了相同的减法:
>>> a = 1671.37
>>> b = 871.37
>>> a - b
799.9999999999999
解决方案是接受浮点数学的限制,并将你的答案四舍五入到所需的精度;或者,切换到另一种数字表示。例如,由于这些值使用两个小数位(美元和美分?),您可以将它们乘以100,并使用整数(仅在显示时除以100,如果需要的话)。然后是二进制编码的十进制和任意精度...我不知道你是如何在Delphi中做的,但它们可能有点过分,取决于你的应用程序。
答案 1 :(得分:1)
嗯,我在Python中获得完全相同的结果;)
Python 2.7.6 (default, Feb 24 2014, 16:00:34)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.2.79)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = 1671.37
>>> b = 871.37
>>> c = 800.00
>>> t = a - c
>>> t = t - b
>>> print t
-1.13686837722e-13
>>>
浮点运算不是100%精确(我只知道解释浮点数如何在内存中表示是很复杂的。)
请在此处阅读此答案: