Delphi 5汇总双变量时的奇怪结果

时间:2013-12-17 13:51:40

标签: delphi floating-point delphi-5

在Delphi 5中,当将两个类型的double和一个正值以及另一个负值相同的值相加时,我会遇到奇怪的问题。

例如

dbv = 50071763.721
crv = -50071763.721

结果应该 0 当两个值相加但我得到的结果有点像 0.0000000074505805969

我在excel中得到了总和我得到0结果。

4 个答案:

答案 0 :(得分:7)

你声称的是虚假的。对于执行计算的IEEE754兼容单元,

x + (-x) = 0 

除了NaN和Inf之外的所有x。

您有两个值,这两个值都不等于问题中的值。我们可以肯定,因为这两个值都不能表示为二进制浮点值。所以,显然你已经四舍五入到小数点三位,但是底层数字不是问题中出现的数字。显然,你的两个值具有不同的绝对值。

有关此主题的必读内容:What Every Computer Scientist Should Know About Floating-Point Arithmetic

答案 1 :(得分:2)

program TestXPlusMinusX;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var dbv, crv : double;

begin
  dbv := 50071763.721;
  crv := -50071763.721;
  if (dbv + crv) = 0 then WriteLn('Sum is Zero');
  WriteLn(dbv + crv);
end.

正如大卫所说,这给了零。既然你没有向我们展示你的实际代码,我们可以说除了你告诉我们的不是你所做的事情。

答案 2 :(得分:1)

尝试对结果进行舍入 例如

uses Math;

function fnSumValue(): Double;
var
  dbv: Double;
  crv: Double;
begin
  dbv := 50071763.721;
  crv := -50071763.721;
  Result := Math.RoundTo(Abs(dbv) - Abs(crv), -6);
end;

答案 3 :(得分:0)

这是由于如何表示浮点数。

你最好的机会是定义你需要的精度,假设为0.001。

将dbv和crv乘以1000(1/1000 = 0.001)并舍入为整数。现在做你的总和。除以1000.这是你需要精确度的结果。

result := (round(dbv*1000)+round(crv*1000))/1000;