我正在尝试一个非常简单的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
答案 0 :(得分:8)
printf
的GNU实现和MacOS(FreeBSD)实现都是不同的程序。两者都旨在与POSIX标准兼容。
POSIX使浮点数的表示形式对printf的实现开放。他们的论点是,shell中的所有计算无论如何都是整数。
因为外壳程序中的所有算术都是整数算术,所以不需要printf()的浮点格式转换规范。 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(例如busybox)带有自己的printf
实现。顺便说一句,我非常惊讶没有人被允许在您的系统上执行命令!
答案 1 :(得分:3)