Pi 的单/双/扩展精度浮点表示精确到小数点后几位?
10 回答
#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
当我检查 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
^
6 位和 14 位。1 位超过 0 为 3 位,虽然存储的最后一位不能被视为一个精度点。
抱歉,如果没有更多上下文,我不知道扩展意味着什么。你的意思是C#的小数点吗?
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.
打印和计数,宝贝,打印和计数。(或阅读规格。)
在 x86 浮点单元 (x87) 中有用于加载某些浮点常量的指令。例如,“fldz”和“fld1”将 0.0 和 1.0 加载到堆栈顶部“st”(又名“st(0)”)。另一个是“fldpi”。
所有这些值都有一个 64 位长的尾数,可以转换为接近 20 个十进制数字。通过 x87 内部使用的 80 位临时浮点格式可以实现 64 位。x87 也可以从 10 字节内存位置加载临时变量并将其存储到 10 字节内存位置。
对于 C 代码,请查看<float.h>
. 这包括float
( FLT_*
)、double
( DBL_*
) 和long double
( LDBL_*
) 定义。
World of PI有 PI 到 100,000,000,000 位,您可以打印和比较。对于一个稍微容易阅读的版本,PI 的喜悦有 10,000 位数字。如果您想自己记住数字,可以尝试学习Cadaeic Cadenza诗。
由于存在用于 pi 的二进制表示的筛方程,因此可以组合变量来存储值的片段以提高精度。此方法对精度的唯一限制是从二进制转换为十进制,但即使是有理数也会遇到问题。
* 编辑:查看这篇文章以获得最新的讨论:使用标准 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);