PI和浮点数的准确性

时间:2009-02-03 16:24:18

标签: floating-point precision floating-accuracy

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

10 个答案:

答案 0 :(得分:23)

#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

答案 1 :(得分:8)

当我查看Quassnoi的回答时,我{Q}}和long double最终会以相同的准确度对我进行挖掘似乎很可疑。如果我运行他用clang编译的代码,我得到了与他相同的结果。但是我发现,如果我指定double后缀并使用文字初始化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;
}

答案 2 :(得分:3)

6个地方和14个地方.1个地方超过0,最后一个地方虽然存储不能被视为精确点。

抱歉,但我不知道扩展意味着没有更多背景。你的意思是C#的小数吗?

答案 3 :(得分:3)

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

答案 4 :(得分:1)

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

所有这些值都有一个64位长的尾数,可转换成接近20位的十进制数字。通过x87内部使用的80位tempreal浮点格式,可以实现64位。 x87可以加载tempreals并将它们存储到10字节的内存位置。

答案 5 :(得分:1)

浮点类型的准确性与PI或任何特定数字无关。它仅取决于该特定类型在内存中存储了多少位数

在IEEE-754的情况下float使用23位尾数,因此精确到23 + 1位精度,或精确到十进制精度~7位。无论π,e,1.1,9.87e9 ......所有这些都以24位存储在一个浮点数中。类似地,double(53位尾数)可以存储15~17个精度的十进制数字。

答案 6 :(得分:0)

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

答案 7 :(得分:0)

对于C代码,请查看<float.h>中的定义。这包括floatFLT_*),doubleDBL_*)和long doubleLDBL_*)定义。

答案 8 :(得分:0)

*编辑:请参阅此帖子以获取最新讨论:Implementation of sinpi() and cospi() using standard C math library *

新的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);

答案 9 :(得分:0)

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