如何在delphi中比较double?

SSE*_*SSE 28 delphi types

我们面临数据类型双重比较的问题:

if(p > pmax) then
begin
  Showmessage('');
end
Run Code Online (Sandbox Code Playgroud)

如果两个值都是100(p = 100和pmax = 100),那么它也会进入if子句.

Lac*_*anG 60

所述Math.pas单元包括功能如SameValue(),IsZero(),CompareValue()该手柄浮动型比较和平等.

const
  EPSILON = 0.0000001;
begin    
  if CompareValue(p, pMax, EPSILON) = GreaterThanValue then
    ShowMessage('p greater than pMax');
Run Code Online (Sandbox Code Playgroud)

常量GreaterThanValue在Types.pas中定义

如果您要比较非常大的值,则不应使用epsilon的常量,而应根据您要比较的值计算epsilon值.

var
  epsilon: double;
begin    
  epsilon := Max(Min(Abs(p), Abs(pMax)) * 0.000001, 0.000001);
  if CompareValue(p, pMax, epsilon) = GreaterThanValue then
    ShowMessage('p greater than pMax');
Run Code Online (Sandbox Code Playgroud)

请注意,如果您使用CompareValue(a, b, 0)或在XE2及更高版本中CompareValue(a, b),Delphi将自动为您填写好的epsilon.

来自德尔福Math单位:

function SameValue(const A, B: Extended; Epsilon: Extended): Boolean;
begin
  if Epsilon = 0 then
    Epsilon := Max(Min(Abs(A), Abs(B)) * ExtendedResolution, ExtendedResolution);
  if A > B then
    Result := (A - B) <= Epsilon
  else
    Result := (B - A) <= Epsilon;
end;
Run Code Online (Sandbox Code Playgroud)

从Delphi XE2开始,现在所有这些函数都有重载,这些函数不需要epsilon参数,而是为您计算一个(类似于为epsilon传递0值).为了代码清晰,我建议调用这些更简单的函数,让Delphi处理epsilon.

在没有epsilon参数的情况下不使用重载的唯一原因是当性能至关重要并且您想要避免重复计算epsilon的开销时.

  • @Johan:-100如果我可以编辑更改的内容.如果您不同意答案,请发布您自己的,然后选择您觉得错误的那个.如果您有语法或格式更改,请进行编辑.如果您不同意答案,请将其投票.将其修改为不同的含义不是如何进行编辑. (10认同)
  • 我觉得永远不会太强烈。如果你知道你的数据总是在一个固定的范围内,为什么要在每次计算时增加重新计算 epsilon 的开销。计算一次合适的 epsilon,然后使 epsilon 恒定。 (2认同)

Too*_*the 12

比较双打有几个问题.一个问题是你所看到的并不完全是因为四舍五入而得到的.你可以有99.999999996423和100.00000000001632,它们都被舍入到100,但它们不相等.

解决方案是使用保证金,这样,如果两个双打的差异在保证金范围内,则接受它们是相等的.

您可以使用边距作为可选参数来创建IsEqual函数:

function IsEqual(const ANumber1, ANumber2: Double; const AMargin: Double = cMargin): Boolean;
begin
  Result := Abs(ANumber1-ANumber2) <= AMargin;
end;
Run Code Online (Sandbox Code Playgroud)

  • 请注意,正确的解决方案已在Math.pas中作为"SameValue"提供. (10认同)