为什么Delphi XE2错误地计算双值?

时间:2014-03-06 20:08:31

标签: delphi-xe2

在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位,都会以同样的方式失败。

为什么这个计算会失败?

2 个答案:

答案 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%精确(我只知道解释浮点数如何在内存中表示是很复杂的。)

请在此处阅读此答案:

https://stackoverflow.com/a/2080642/756056