Delphi 四舍五入

  Delphi 的四舍五入跟我们平常所认识的四舍五入不一样。它用的是银行家算法-也就是四舍六入,而五入不入取决后面跟的一位
数是奇数还是偶数,如果是奇数则进,如果是偶数则舍。简单说是奇进偶不进。
  举例: 123.3359保留两位小数,如果是平常四舍五入123.3359 = 123.34,如果是银行家算法123.34;结果是一样;
          123.3358保留两位小数,如果是平常四舍五入123.3358= 123.34,如果是银行家算法123.33;结果不一样;

  在以前开发的系统时做薪资结算,就遇到这样的问题。无论是Round 还是FormatFloat都用的银行算法,偏偏会计用四舍五入,所以两边一对总是差了一分钱。为这一分钱足足整了三个月都没搞定,百度、Google问的人多,解决问题的少。在“床上等你”发贴也没搞定,看来这个问题虽然看似简单,但好像大多数没搞定。后来还是一个偶然的机会改进了一个Delphi四舍五入函数才解决。

  原理: SimpleRoundTo是一个四舍五入的函数,应用效果入下:
          SimpleRoundTo(1234567, 3)  1234000
          SimpleRoundTo(1.234, -2)  1.23
          SimpleRoundTo(1.235, -2)  1.24
          SimpleRoundTo(-1.235, -2)  -1.23

  SimpleRoundTo对于正数四舍五入没问题上,但是遇到负数就是直接舍去了。注意第四个impleRoundTo(-1.235, -2)  -1.23,实际
应该是-1.24。所以对SimpleRoundTo函数进行了改进。如果是正数则直接用SimpleRoundTo函数,如果负数先取绝对值,然后使用SimpleRoundTo函数,然后再取反。

如果还有那位大神有更简洁、更高效、更好用的写法,欢迎跟贴。

 

使用方法: 1.235保留两位小数 SimpleRoundEx(1.235, -2) = 1.24;

               -1.235保留两位小数 SimpleRoundEx(-1.235, -2) = -1.24

 
//四舍五入
function SimpleRoundEx(const AValue: Double; const ADigit: Integer): Double;

//四舍五入
function TBaseForm.SimpleRoundEx(const AValue: Double;
  const ADigit: Integer): Double;
begin
  if (Sign(AValue) = 1) or (Sign(AValue) = 0) then
    begin
      Result := SimpleRoundTo(AValue, ADigit);
    end
  else
    begin
      Result := SimpleRoundTo(Abs(AValue), ADigit) * (-1);
    end;
end;


_________________________________________________________________________________________________

鉴于有同学说这个方法不靠谱,这是里再提供一种方法(注:是从网上搬来的,具体地址没记住)


class function TNewDcFunc.RoundFloat(f:double;i:integer):double;
var
  s:string;
  ef:extended;
begin
  s:='#.'+ StringOfChar('0',i);
  ef:=StrToFloat(FloatToStr(f));//防止浮点运算的误差
  result:=StrToFloat(FormatFloat(s,ef));
end;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值