printf 如何四舍五入到小数点后第一位?

printf 如何四舍五入到小数点后第一位?

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使用常规doubles。您看到的舍入行为是因为(例如)1.45 不能表示为 2 的幂之和,这就是IEEE 754 浮点表示有效,并且最接近的近似值根据精度而变化。它稍微多一些(80 位)或少一些(64 位),因此如您所见,向上或向下舍入。

与以往一样,如果您关心准确的人类水平表示和舍入,请不要使用浮点。

相关内容