Printf

printf 如何四捨五入到小數點後一位?

  • February 21, 2017

我正在printf我的系統上測試兩種不同的實現:printf (GNU coreutils) 8.26,以及與zsh 5.3.1. 我正在測試半數如何四捨五入,即 1.5、2.5、3.5、… 9.5。

$ for i in {1..9}; do /usr/bin/printf '%.0f\n' "${i}.5"; done
2
2
4
4
6
6
8
8
10
$ for i in {1..9}; do printf '%.0f\n' "${i}.5"; done
2
2
4
4
6
6
8
8
10

在這裡,兩者顯然都是四捨五入。但是,當我測試四捨五入到小數點後,事情變得混亂。也就是說,我正在測試 1.15、1.25、1.35、… 1.95。

$ for i in {1..9}; do /usr/bin/printf '%.1f\n' "1.${i}5"; done
1.1
1.2
1.4
1.5
1.5
1.6
1.8
1.9
2.0
$ for i in {1..9}; do printf '%.1f\n' "1.${i}5"; done
1.1
1.2
1.4
1.4
1.6
1.6
1.8
1.9
1.9

兩種實現方式都不同,我也看不到任何清晰的模式。這兩個 s 如何將printf一半舍入到小數點後一位?

GNU printf使用long double而 zsh使用正常doubles。您看到的捨入行為是因為(例如)1.45 不能表示為 2 的冪的總和,這是IEEE 754 浮點表示的工作原理,並且最接近的近似值根據精度而變化。它略多(80 位)或更少(64 位),因此如您所見,向上或向下舍入。

與以往一樣,如果您關心準確的人類級別表示和舍入,請不要使用浮點數。

引用自:https://unix.stackexchange.com/questions/346477