【发布时间】:2018-05-12 12:40:07
【问题描述】:
我很熟悉这样一个事实,即十进制分数通常不能很好地转换为二进制,因此存储了一个近似值,当转换回十进制时,它与原始数字有点偏离。我相信 0.21 就是这种分数的一个例子。
这个程序如何以及为什么在 gcc 中编译时准确显示 7.21?
而且(这个问题的重要第二部分),为什么它准确地显示 7.21,它是否不准确地显示 839.21?
我可以理解为什么它会不准确地显示 0.21 或任何数字点 21 不准确,因为它需要很多位才能准确地将它放入二进制中,即使是一个。但我希望它始终不准确地显示n.21,不管整数 n 是什么
printf("%.100f\n", 7.21);
printf("%.100f\n", 839.21);
produces 7.210000000000000000000...
839.2100000000000400000....
知道为什么它做的一个准确,一个不准确吗? (无论如何在我的 gcc 编译器上!)
如果相关,gcc --version 显示gcc.exe (rubenvb-4.5.4) 4.5.4
Copyright (C) 2010 Free Software Foundation, Inc.
我和一个人交谈过,他说他得到的两个都是不准确的,这是人们所期望的。所以我拍摄了一个屏幕展示来展示这种行为
注意- 我注意到我的 cygwin gcc 实现不是最新的 cygwin gcc 实现.. 我刚刚做了 where gcc 它是从 C:\Perl64\site\bin\gcc.exe 运行它,所以它没有运行 cygwin一。它可能正在运行一个旧的 ming (这是 R 建议的)。 chux 是 cygwin n GNU C11 (GCC) 版本 6.4.0 (i686-pc-cygwin)`。
【问题讨论】:
-
试试
volatile double x = 7.21; printf("%.100f\n", x);看看优化是否在起作用。 -
@chux volatile double 也精确地打印 7.21
-
感谢您的检查。我相信问题是带有 FP 参数的弱
printf()。如果您的编译器可能,请使用printf("%a\n", x);查看十六进制有效数。 -
@chux
0x1.cd70a4p+2弱 printf() 是什么意思? -
barlop,
printf("%.100f\n", 7.21);是真正的代码还是打印float?甚至您的printf("%a\n"...也可能很弱。0x1.cd70a4p+2预计与volatile float x = 7.21; printf("%a\n", x);一起使用