14

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

4

10 回答 10

25
#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;
}

结果:

[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
于 2009-02-03T16:38:43.917 回答
17

当我检查 Quassnoi 的答案时,我觉得这很可疑,long double并且double最终会得到同样的准确性,所以我挖了一点。如果我运行他用 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;
}

结果:

3.14159265358979323846264338327950288419716939937510582097494459230781640628620899

3.14159274101257324218750000000000000000000000000000000000000000000000000000000000
        ^
3.14159265358979311599796346854418516159057617187500000000000000000000000000000000
                 ^
3.14159265358979323851280895940618620443274267017841339111328125000000000000000000
                    ^
于 2014-03-28T18:45:03.733 回答
3

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

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

于 2009-02-03T16:30:29.707 回答
1

Accuracy of a floating-point type is not related to PI or any specific numbers. It only depends on how many digits are stored in memory for that specific type.

In case of IEEE-754 float uses 23 bits of mantissa so it can be accurate to 23+1 bits of precision, or ~7 digits of precision in decimal. Regardless of π, e, 1.1, 9.87e9... all of them is stored with exactly 24 bits in a float. Similarly double (53 bits of mantissa) can store 15~17 decimal digits of precision.

于 2013-08-08T00:21:37.277 回答
1

打印和计数,宝贝,打印和计数。(或阅读规格。)

于 2009-02-03T16:36:51.613 回答
1

在 x86 浮点单元 (x87) 中有用于加载某些浮点常量的指令。例如,“fldz”和“fld1”将 0.0 和 1.0 加载到堆栈顶部“st”(又名“st(0)”)。另一个是“fldpi”。

所有这些值都有一个 64 位长的尾数,可以转换为接近 20 个十进制数字。通过 x87 内部使用的 80 位临时浮点格式可以实现 64 位。x87 也可以从 10 字节内存位置加载临时变量并将其存储到 10 字节内存位置。

于 2011-08-18T19:52:26.937 回答
0

对于 C 代码,请查看<float.h>. 这包括float( FLT_*)、double( DBL_*) 和long double( LDBL_*) 定义。

于 2009-02-04T08:47:48.063 回答
0

World of PI有 PI 到 100,000,000,000 位,您可以打印和比较。对于一个稍微容易阅读的版本,PI 的喜悦有 10,000 位数字。如果您想自己记住数字,可以尝试学习Cadaeic Cadenza诗。

于 2009-02-03T17:01:30.830 回答
0

由于存在用于 pi 的二进制表示的筛方程,因此可以组合变量来存储值的片段以提高精度。此方法对精度的唯一限制是从二进制转换为十进制,但即使是有理数也会遇到问题。

于 2016-03-15T05:53:24.160 回答
0

* 编辑:查看这篇文章以获得最新的讨论:使用标准 C 数学库实现 sinpi() 和 cospi() *

新的 math.h 函数__sinpi()__cospi()我解决了 90 度等直角的问题。

cos(M_PI * -90.0 / 180.0) returns 0.00000000000000006123233995736766
__cospi( -90.0 / 180.0 )      returns 0.0, as it should

/*  __sinpi(x) returns the sine of pi times x; __cospi(x) and __tanpi(x) return
the cosine and tangent, respectively.  These functions can produce a more
accurate answer than expressions of the form sin(M_PI * x) because they
avoid any loss of precision that results from rounding the result of the
multiplication M_PI * x.  They may also be significantly more efficient in
some cases because the argument reduction for these functions is easier
to compute.  Consult the man pages for edge case details.                 */
extern float __cospif(float) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA);
extern double __cospi(double) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA);
extern float __sinpif(float) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA);
extern double __sinpi(double) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA);
extern float __tanpif(float) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA);
extern double __tanpi(double) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_NA);
于 2015-11-24T19:02:13.773 回答