首页 文章

Delphi XE2使用DecimalRounding_JH1进行舍入

提问于
浏览
0

由于Delphi XE2中存在记录的舍入问题,我们在Embarcadero站点上使用了一个名为DecimalRounding_JH1的特殊舍入单元来实现真正的银行家舍入 . 可在此处找到该单位的链接:

DecimalRounding_JH1

使用此单位的DecimalRound函数,其中包含大量小数位数的数字

这是DecimalRounding_JH1单元的舍入例程 . 在我们的示例中,我们使用以下参数调用此DecimalRound函数(166426800,12,MaxRelErrDbl,drHalfEven)其中maxRelErrDbl = 2.2204460493e-16 * 1.234375 * 2

Function DecimalRound(Value: extended; NDFD: integer; MaxRelErr: double;
                         Ctrl: tDecimalRoundingCtrl = drHalfEven): extended;
{ The DecimalRounding function is for doing the best possible job of rounding
  floating binary point numbers to the specified (NDFD) number of decimal
  fraction digits.  MaxRelErr is the maximum relative error that will allowed
  when determining when to apply the rounding rule.  }
var i64, j64: Int64; k: integer; m, ScaledVal, ScaledErr: extended;
begin

  If IsNaN(Value) or (Ctrl = drNone)
    then begin Result := Value; EXIT end;

  Assert(MaxRelErr > 0,
      'MaxRelErr param in call to DecimalRound() must be greater than zero.');

{ Compute 10^NDFD and scale the Value and MaxError: }
  m := 1; For k := 1 to abs(NDFD) do m := m*10;
  If NDFD >= 0
    then begin
      ScaledVal := Value * m;
      ScaledErr := abs(MaxRelErr*Value) * m;
      end
    else begin
      ScaledVal := Value / m;
      ScaledErr := abs(MaxRelErr*Value) / m;
      end;

{ Do the diferent basic types separately: }
  Case Ctrl of
    drHalfEven: begin
      **i64 := round((ScaledVal - ScaledErr));**

最后一行是我们得到浮点错误的地方 .

有关为何发生此错误的任何想法?

1 回答

  • 0

    如果出现异常,则表示您无法在指定的误差范围内将值表示为double .

    换句话说, maxRelErrDbl 太小了 .

    尝试使用 maxRelErrDbl = 0,0000000001 或其他东西来测试我是否正确 .

相关问题