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 ,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类型可以很好的来避免。 |