c - C中float和double之间的精度

标签 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. 为什么将整数添加到 float 最终会成为第二个输出,但将 float 更改为 double 会解决第三个输出的问题?
  2. 为什么第三个输出与第一个和第二个输出的小数点后位数相同,因为它应该是更精确的值?

最佳答案

它们产生相同小数位数的原因是因为 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/

相关文章:

c++ - 获取控制台句柄

c - 如何处理复杂 C 代码中的多个参数选项

常量的正确定义

android - 在 Android NDK 中使用 GL_EXT_color_buffer_half_float

java - 将一个数除以 5,得到重量比并用它来分割另一个数

c - 结构体列表、成员删除

php - 检查数字是否在 PHP 中 float

c++ - g++编译器中奇怪的将转换范围缩小为两倍到 float 警告

C#:(float) (x/y) 和 x/(float) y 之间有区别吗?

math - float 学有问题吗?