C中浮点数和双精度数之间的精度

时间:2019-04-14 16:00:50

标签: c floating-point precision

我知道有几个主题与我的相同,但我仍然没有真正理解它,因此我希望有人可以以一种更简单但明确的方式为我解释该主题,而不是粘贴其他主题的链接,谢谢

这是示例代码:

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

我的两个问题是:

  1. 为什么将整数添加到浮点数最终作为第二个输出,但是将浮点数更改为double可以解决作为第三输出的问题?
  2. 为什么第三输出的小数点后的位数与第一和第二输出的位数相同?

2 个答案:

答案 0 :(得分:1)

之所以产生相同的小数位数,是因为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用十进制表示)。

答案 1 :(得分:0)

  1. 我认为在两种情况下,a * 0.001的计算都将以双精度进行,然后将其存储为浮点数会损失一些精度。
  2. 您可以通过以下方式选择由printf打印多少个十进制数字: “%.10lf”(获取10位数字),而不仅仅是“%lf”。