我在 OSX Mavericks 上,尝试学习 shell 和 awk 中的 printf
命令。我正在尝试不同的格式说明符和字段精度值。
我得到了一个非常意想不到的结果,我真的不明白为什么。
这是我的代码:
#!/bin/bash
a="12345.123456789012345678901"
printf "(%40.30s)\n" $a
printf "(%40.30f)\n" $a
printf "(%40.30e)\n" $a
我本来希望看到这样的东西:
( 12345.123456789012345678901)
( 12345.123456789012345678901000000000)
( 1.234512345678901234567890100000e+04)
但是,这是我的实际结果:
( 12345.123456789012345678901)
( 12345.123456789011470391415059566498)
( 1.234512345678901147039141505957e+04)
第一行按预期工作,但第二行和第三行显示的数字(分别带有 %f
和 %e
)却没有。请注意,前 11 位小数已正确显示,但其余部分未正确显示。
我使用 printf
中的 awk
进行了仔细检查,并得到了相同的修改后的数字。 (我实际上不知道这一点,但根据我的测试,awk printf
和 shell printf
的行为不同,这就是我也在 awk
中测试它的原因。)
我认为这与四舍五入没有任何关系。我是否无意中触发了某些八进制或十六进制系统?
谢谢。
最佳答案
17 位有效数字超出了 64 位 float 的限制(根据 IEEE 754 double 二进制浮点格式的定义,有效精度为 53 位,指数为 11 位)。换句话说,您的数字位数太多,无法准确表示为 64 位 float 。小数点左边或右边有多少位并不重要:数字总和很重要 - 小数点的位置在内部由指数表示。因此你有 11+5 位数字 - 即 16 个正确的数字。除此之外,就是精度的损失。
关于macos - printf 改变输入数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24804849/