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
四舍五入到小数点后第一位?
答案1
GNU 打印函数用途long double
而zsh使用常规double
s。您看到的舍入行为是因为(例如)1.45 不能表示为 2 的幂之和,这就是IEEE 754 浮点表示有效,并且最接近的近似值根据精度而变化。它稍微多一些(80 位)或少一些(64 位),因此如您所见,向上或向下舍入。
与以往一样,如果您关心准确的人类水平表示和舍入,请不要使用浮点。