c - 为什么 sqrt() 分配的这个 float 没有精度损失?

标签 c precision

<分区>

我想了解 C 如何处理 float 的精度损失。

这是我的简单代码:

#include <stdio.h>
#include <math.h>

int main ()
{
    double a;
    int i;
    i = 7;
    a = sqrt(i);

    printf("i = %d, a = %lf\n", i, a); 
    printf("a * a = %lf\n", a*a);

    a = 2.645751;
    printf("a * a = %lf\n", a*a);

    return(0);
}

下面是cc后的结果

i = 7, a = 2.645751

a * a = 7.000000

a * a = 6.999998

如果直接分配一个 float 2.645751,a * a 的结果在我看来是可以理解的。

但是如果a被赋值为sqrt(7),为什么a * a的输出没有精度损失呢?

我很难理解。

最佳答案

您的困惑来自 a 中实际保存的内容以及 printf 打印的默认精度。来自 man 3 printf “如果缺少精度,则取为 6”。因此,当您使用 %lf 打印时(应该只是 %f,因为 %f 已经是格式说明符对于 double),您只能看到默认 6 位精度的 a 值。 (四舍五入)

a 在您调用 a = sqrt(i); 后不包含 2.645751 - 这只是默认精度输出你的 printf 语句。您可以通过为输出指定更长的精度来清楚地看到这一点,例如

printf("i = %d, a = %.10f\n", i, a); 

输出:

i = 7, a = 2.6457513111

因此,您需要弄清楚实际 double 中包含的内容很可能不是您在使用带有默认 格式说明符的 printf 时看到的内容 和默认的精度double 值(64 位)表示 1 位 符号位、11 位 归一化指数和 52-位 尾数。并非所有数字都能够准确表示(只是由于表示每个可能数字的位数有限)。

一个很好但可以说读起来相当枯燥的引用文献是 What Every Programmer Should Know About Floating-Point

让我知道这是否有助于您的理解,或者您是否还有疑问。我们很乐意提供进一步的帮助。

关于c - 为什么 sqrt() 分配的这个 float 没有精度损失?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48046488/

相关文章:

从 char16_t* 复制到 char16_t*

algorithm - 精确高效绘图的技术和算法

java - double 在不同语言中是不同的

Python numpy float16 数据类型操作,和 float8?

c - 将结构中的二维数组分配给二维数组

c - GLFW3 中是否有 glutDisplayFunc 等效项?

c++ - 管理 C++ 单精度和 double 混合计算的规则是什么?

testing - 关于比较 float 的容差和公式的原则性推理?

C 正则表达式搜索和存储多个组

c - C中的这段代码是否属于未定义行为类别?