我有一个问题,我使用printf将浮点数舍入到正确的小数点数。我得到了不一致的结果,如下所示。
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
我已经看到过计算中的浮点数可能会导致问题的例子,但是没想到这会带来格式化。
答案 0 :(得分:3)
数字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的答案仅与可以精确表示为二进制数的数字相关,即。即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
答案 1 :(得分:1)
我在Python中尝试了类似的东西并得到了类似的结果:
_bla
这似乎是一致的浮动点浮动,特别是考虑到104.445的浮点表示小于实际数学值104.445:
>>> round(104.445, 2)
104.44
>>> round(104.4445, 3)
104.445
答案 2 :(得分:0)
我强烈怀疑这种行为的原因与awk的关系不如计算机存储数字的方式。正如user31264所述:&#34;您的计算机不知道这样的数字[如104.4445]。&#34;
以下是我在Pale Moon Web浏览器中使用JavaScript Scratchpad进行的实验结果:
(104.45).toFixed(55)
/*
104.4500000000000028421709430404007434844970703125000000000
*/
(104.445).toFixed(55)
/*
104.4449999999999931787897367030382156372070312500000000000
*/
(104.4445).toFixed(55)
/*
104.4445000000000050022208597511053085327148437500000000000
*/
很可能,你的awk解释器不处理十进制数104.45等,而是使用&#34; wonky&#34;这里显示的值。围绕其中的第一,第二和第三个&#34; wonky&#34;分别为1,2和3个小数位的值将给出与awk解释器给你相同的结果。