我正在尝试一个非常简单的printf
测试:
printf "%.16f\n" 5.10
在linux上我得到了这个输出:5.100000000000000000
,这是预期的。
但是OS / X上的测试产生了同样的结果:5.0999999999999996
为什么printf
会产生不同的输出?
编辑:这不是C代码,printf
也是一个命令行实用程序,方便脚本和测试。
下面的等效C程序产生5.100000000000000000
:
#include <stdio.h>
int main() {
printf("%.16f\n", 5.10);
return 0;
}
编辑2:情节变厚......使linux用户更有趣,如果我以nobody
运行此命令,我会得到与OS / X相同的行为:
chqrlie$ printf "%.18f\n" 5.10
5.100000000000000000
chqrlie$ su nobody -c 'printf "%.18f\n" 5.10'
5.099999999999999645
GNU实现和printf
的MacOS(FreeBSD)实现都是不同的程序。两者都旨在与POSIX标准兼容。
POSIX将浮点数的表示留给printf的实现。他们的论证是shell中的所有计算都是整数。
不需要printf()的浮点格式转换规范,因为shell中的所有算术都是整数运算。 awk实用程序执行浮点计算并提供自己的printf函数。 bc实用程序可以执行任意精度的浮点运算,但不提供广泛的格式化功能。 (此printf实用程序实际上不能用于格式化bc输出;它不支持任意精度。)鼓励实现支持浮点转换作为扩展。
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/printf.html
PS:
5.1
不是bash中的浮点数。 bash不支持浮点数。
5.1
是一个字符串,由printf
解释,具体取决于区域设置(!)
theymann@theymann-laptop:~/src/sre/inventory-schema$ LANG=en_US.UTF8 printf "%.16f\n" 5.10
5.1000000000000000
theymann@theymann-laptop:~/src/sre/inventory-schema$ LANG=de_DE.UTF8 printf "%.16f\n" 5.10
bash: printf: 5.10: Ungültige Zahl. # << German: Bad Number
0,0000000000000000
注意:在德国,我们使用小数分隔符。
普通用户和无人之间的输出差异必须是使用的shell。一些shell,像busybox一样自带printf
。顺便说一下,我很惊讶没有人被允许在你的系统上执行命令!