Delphi——Trunc函数精度的问题

var
a , b, c ,d : Double;
i : Integer;
begin
a := 0.3;
b := 0.3;
c := 300000;

d := a * b * c;
i := Trunc(d);//26999不是 27000
Memo1.Lines.Add('d := a * b * c; i := Trunc(d)='+IntToStr(i));
i := Trunc(d * 10000);//269999999 不是 270000000
Memo1.Lines.Add('d := a * b * c; i := Trunc(d)='+IntToStr(i));
end;

怎么才能让Trunc得到我想要的精度?
尝试在trunc前加一个很小的值

d := d+ 1e-11;
i := Trunc(d);
有效
d := d+ 1e-12;
i := Trunc(d);
则仍然有刚才的问题。


其他语言,例如c、c#尝试同样数值的乘法并取整没有这种问题。
浮点数精度上有问题但总觉得round有差异是可以理解,怎么在delphi中一个很正常的数取整也有问题呢?

解答:
在计算机中浮点数的表达是近似值,a*b*c是近似=27000,而这里刚好得到的是26999.999999999996362,所以出现了Trunc(d)=26999的情况,为避免这种情况出现,
特别是在金融等的计算上面,往往需要限定d的精度,否则会出现这种微小的误差,而这误差累积起来,就会出现大的bug。a,b,c可以是double,但是结果不能用高精度的类型,设置为低精度的Single或者Currency类型可以很好的来避免。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值