PI和浮点数的准确性

11 floating-point precision floating-accuracy

Pi的单/双/扩展精度浮点表示精确到小数位数?

Qua*_*noi 24

#include <stdio.h>

#define E_PI 3.1415926535897932384626433832795028841971693993751058209749445923078164062

int main(int argc, char** argv)
{
    long double pild = E_PI;
    double pid = pild;
    float pif = pid;
    printf("%s\n%1.80f\n%1.80f\n%1.80Lf\n",
    "3.14159265358979323846264338327950288419716939937510582097494459230781640628620899",
    pif, pid, pild);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

结果:

[quassnoi #] gcc --version
gcc (GCC) 4.3.2 20081105 (Red Hat 4.3.2-7)

[quassnoi #] ./test

3.14159265358979323846264338327950288419716939937510582097494459230781640628620899

3.14159274101257324218750000000000000000000000000000000000000000000000000000000000
        ^
3.14159265358979311599796346854418516159057617187500000000000000000000000000000000
                 ^
3.14159265358979311599796346854418516159057617187500000000000000000000000000000000
                 ^
  0000000001111111
  1234567890123456
Run Code Online (Sandbox Code Playgroud)

  • @Bombe:更正了,你现在可以投票给你+1了:) (3认同)
  • 当然,这就是我把 gcc --version 放在那里的原因 (2认同)
  • 此测试对于扩展精度结果无效,因为 pi 的 #define 文字是双精度的。你需要它是一个扩展的精度文字。见[这个](http://stackoverflow.com/questions/21557816/whats-the-c-suffix-for-long-double-literals)。 (2认同)
  • `E_PI` 必须有 `L` 后缀以获得长双精度,否则它会卡在双精度上 (2认同)

the*_*red 8

当我检查Quassnoi的答案似乎可疑,我认为long doubledouble让我在一个小挖最终会得到相同的精度.如果我运行他用clang编译的代码,我得到了与他相同的结果.但是我发现如果我指定long double后缀并使用文字初始化long double,它提供了更多的精度.这是我的代码版本:

#include <stdio.h>

int main(int argc, char** argv)
{
    long double pild = 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899L;
    double pid = pild;
    float pif = pid;
    printf("%s\n%1.80f\n%1.80f\n%1.80Lf\n",
        "3.14159265358979323846264338327950288419716939937510582097494459230781640628620899",
        pif, pid, pild);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

结果如下:

3.14159265358979323846264338327950288419716939937510582097494459230781640628620899

3.14159274101257324218750000000000000000000000000000000000000000000000000000000000
        ^
3.14159265358979311599796346854418516159057617187500000000000000000000000000000000
                 ^
3.14159265358979323851280895940618620443274267017841339111328125000000000000000000
                    ^
Run Code Online (Sandbox Code Playgroud)


Rob*_*uld 4

6位和14位。3位中的1位超过0,最后一位虽然已存储,但不能被视为精度点。

抱歉,如果没有更多上下文,我不知道扩展意味着什么。你是说C#的小数吗?