有系统用户反映,在其中使用delphi6的程序中计算一个数值为2.64,但是在另外一个模块中,相同的参数,计算出来却是2.63,之间相差了0.01。一查,后者是调用oracle中存储过程实现的,而前者在delphi6中实现。
在 仔细分析原因后,发现delphi 6中使用roundto或者simpleroundto都不是我们通常说的四舍五入,前者是采用银行家的四舍五入,即四舍六入五奇偶,而 simpleroundto这个函数也令人有点琢磨不透,有些是四舍五入,有些不是,比如对于 simpleroundto(12.95,-1)=12.9。
而在PL/SQL中,一律保留了1位,四舍五入,所以两种方法一比较,最后累计,就出现了误差。
解决方法,可以自己编辑一个函数处理,也可以按照下面一个网友的解释进行处理:
http://www.2ccc.com/idea.asp?articleid=1300 网友iamdream
以下是研究的结果(Delphi6):
RoundTo(及Round)函数使用所谓“银行家舍入法”<Banker’s Rounding>(对于舍入位后为5的情况,则舍入位为偶数,则舍,为奇数,则入),而Format函数则为正常的四舍五入法,取例如下:
0.145 RoundTo(0.145, -2) = 0.14
0.145 Format(‘%8.2f’, 0.145) = 0.15
0.155 RoundTo(0.155, -2) = 0.16
0.155 Format(‘%8.2f’, 0.155) = 0.16
另在进行浮点数的运算时,可能会出现0.14499999999999的情况,此时的值按数学上要求实际应为0.145,如用以上方法舍入到小数点后两位时,均不能达到想要的效果。
另SimpleRoundTo比RoundTo更接近四舍五入法,但不完全是四舍五入,如对0.145用SimpleRoundTo(0.145, -2)舍入时仍为0.14;
如果后面还有小数,如0.1450000001,此时舍入,则三者均为0.15!对1.145,SimpleRoundTo舍入为1.15!
故而如用RoundTo来四舍五入,则可在舍入位后的第二位加上5,如0.145,则加上0.0005,此时成为0.1455,再舍入时,就为0.15了!
因此四舍五入取两位小数时,只要先加上0.0001,然后用RoundTo或SimpleRoundTo即可。
最近留言