我知道有几个主题与我的相同,但我仍然不太明白,所以我希望有人可以用更简单但明确的方式为我解释这一点,而不是粘贴其他主题的链接,谢谢.
这是一个示例代码:
int a = 960;
int b = 16;
float c = a*0.001;
float d = a*0.001 + b;
double e = a*0.001 + b;
printf("%f\n%f\n%lf", c, d, e);
输出:
0.960000
16.959999
16.960000
我的两个问题是:
- 为什么将整数添加到 float 最终会成为第二个输出,但将 float 更改为 double 会解决第三个输出的问题?
- 为什么第三个输出与第一个和第二个输出的小数点后位数相同,因为它应该是更精确的值?
最佳答案
它们产生相同小数位数的原因是因为 6
是默认值。您可以更改它,如下面编辑的示例所示,其中语法为 %.*f
。 *
可以是如下所示的数字,或者在第二种情况下,作为另一个参数提供。
#include <stdio.h>
int main(void) {
int a = 960;
int b = 16;
float c = a*0.001;
float d = a*0.001 + b;
double e = a*0.001 + b;
printf("%.9f\n", c);
printf("%.*f\n", 9, d);
printf("%.16f\n", e);
}
程序输出:
0.959999979 16.959999084 16.9600000000000009
额外的小数位现在表明没有一个结果是准确的。原因之一是 0.001
无法精确编码为浮点值。还有其他原因,这些原因已被广泛讨论。
理解原因的一个简单方法是,float
具有大约 2^32
可以编码的不同值,但是其中有无穷多个实数float
的范围,并且只有大约 2^32
可以准确地表示。对于分数 1/1000
,二进制表示它是一个循环值(十进制分数 1/3
也是如此)。
关于c - C中float和double之间的精度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55677268/