我在使用 printf 将 float 四舍五入到正确的小数位数时遇到问题。我得到的结果不一致,如下所示。
echo 104.45 | awk '{printf "%.1f\n",$1}'
104.5 <-- seem to be correct behaviour
echo 104.445 | awk '{printf "%.2f\n",$1}'
104.44 (should be 104.45) <-- seems to be INCORRECT behaviour
echo 104.4445 | awk '{printf "%.3f\n",$1}'
104.445 <-- seems to be correct behaviour
我见过这样的例子,计算中的 float 可能会导致问题,但没想到格式化会出现这种情况。
数字 104.4445 不能精确表示为二进制数。换句话说,您的计算机不知道这样的数字。
# echo 104.4445 | awk '{printf "%.20f\n",$1}'
104.44450000000000500222
# echo 104.445 | awk '{printf "%.20f\n",$1}'
104.44499999999999317879
这就是为什么前者四舍五入为 104.445,而后者四舍五入为 104.44。
sjsam 的答案只与可以精确表示为二进制数 i 的数字有关。 e. m/2**n
,其中 m
和 n
是整数并且不会太大。将 ROUNDINGMODE 更改为“A”对打印 104.45、104.445 或 104.4445 完全没有影响:
# echo 104.4445 | awk -v ROUNDMODE="A" '{printf "%.3f\n",$1}'
104.445
# echo 104.4445 | awk '{printf "%.3f\n",$1}'
104.445
# echo 104.445 | awk -v ROUNDMODE="A" '{printf "%.2f\n",$1}'
104.44
# echo 104.445 | awk '{printf "%.2f\n",$1}'
104.44