Delphi-使用FormatFloat('0。##',argValue)时,浮点取整不一致

时间:2018-12-10 14:54:18

标签: delphi

尝试使用函数FormatFloat(格式为字符串'0.##')将双精度值四舍五入到小数点后两位。

下面是inputoutput

231.545 -> 231.54 (but expected output is 231.55)
2.315 -> 2.31 (but expected output is 2.32)

23.045 -> 23.05 (gives expected output 23.05)
23.145 -> 23.14 (but expected output 23.15)

23.245 -> 23.25 (gives expected output 23.25)
23.345 -> 23.34 (but expected output 23.35)

23.445 -> 23.45 (gives expected output 23.45)
23.545 -> 23.55 (gives expected output 23.55)
23.645 -> 23.65 (but expected output 23.64)

23.745 -> 23.75 (gives expected output 23.75)
23.845 -> 23.84 (but expected output 23.84)
23.945 -> 23.95 (gives expected output 23.95)

为什么发生这种奇怪的行为?我正在使用Delphi 7。

1 个答案:

答案 0 :(得分:5)

二进制浮点值不能完全代表每个值。这就是您所看到的。

例如,值2.315用双精度表示:

2.31499 99999 99999 94670 92948 17992 48605 96656 79931 64062 5

这将四舍五入为2.31


如果您可以使用十进制数据类型(例如currency),则可以获得所需的输出(如果货币在您的工作范围之内):

var
  c : Currency;
begin
  c := 2.315;
  WriteLn(FormatFloat('0.##',c)); // Outputs 2.32
end.

一种替代方法是使用十进制库,例如BigDecimals,但这将需要现代的Delphi版本并支持带有方法的记录。