德尔福错误的双精度计算

Fel*_*ipe 1 delphi floating-point

我在使用双精度变量计算简单算术方程时遇到问题.

我有一个具有属性值的组件具有双精度,我将此属性设置为100.

然后我做一个简单的减法来检查这个值是否真的是100:

var
check: double;
begin
  check:= 100 - MyComponent.Value
  showmessage(floattostr(check));
end;
Run Code Online (Sandbox Code Playgroud)

问题是我没有得到零,我得到-1.4210854715202E-14,这是一个问题,因为我程序检查这个结果是否正好为零

任何想法如何解决?

Dav*_*nan 5

虽然您另有说明,但返回的值MyComponent.Value显然不完全相等100.如果是的话,则100 - MyComponent.Value完全等于0.我们可以说因为100在二进制浮点中是完全可表示的.

这很容易看到100.0 - 100.0 = 0.0.

var
  x, y: Double;
....
x := 100.0;
y := 100.0;
Assert(x-y=0.0);
Run Code Online (Sandbox Code Playgroud)

在您的场景中,您会发现

MyComponent.Value = 100.0
Run Code Online (Sandbox Code Playgroud)

评估为False.

通常,尝试精确比较浮点值总是一件危险的事情.特别是如果值是算术运算的结果,那么浮点运算的固有不精确性将意味着精确比较通常不会给出您期望的结果.

我假设MyComponent.Value实际上执行算术而不是像你声称的那样返回100.0.

有时,检查与浮点值相等的最佳方法是检查大致相等.例如,abs(x-y)<tol哪里tol是一些小数字.难点在于,很难提出一个强有力的选择 tol.

如果不了解更多细节,很难说你应该如何实施这个测试.

  • 肯定是100%,值不是100.如果是,MyComponent.Value = 100将评估为True.它不会.当您使用FormatFloat时,您将四舍五入到少数有效数字. (2认同)
  • 如果你仍然不相信我,试试这个:`ShowMessage(FormatFloat('#.####### E - ##',99.999999999)) (2认同)