PI的定义很长

时间:2014-03-13 22:13:58

标签: c pi

我正在调试一些旧的C代码,它有一个定义#define PI 3.14 ......其中......大约有50个其他数字。

这是为什么?我说我可以将数字减少到大约16位小数,但是我的老板对我咆哮说其他数字用于平台独立性和向前兼容性。但是程序会慢下来吗?

2 个答案:

答案 0 :(得分:7)

不,这不会减慢程序的速度,除非你运行的是一个令人难以置信的动力不足的1MHz DSP芯片,它必须在软件中进行浮点运算,而不是将其传递给专用的FPU。这意味着使用浮点数据的任何数学运算都比使用整数运算慢得多。

一般来说,如果程序中最耗时的部分快速连续进行大量计算,浮点计算速度特别慢,那么更高的精度只会导致速度减慢。在现代CPU上,通常情况并非如此,可能的例外是某些芯片会导致浮点下溢之类的80个周期停顿。这类问题可能超出了这个问题的范畴。

首先,最好使用PI的通用标准定义,例如C标准标题<math.h>,其中定义为#define M_PI 3.14159265358979323846。如果你坚持,你可以继续手动定义它。

此外,C中当前可用的最佳精度相当于大约19位数。

  

根据维基百科,80位&#34;英特尔&#34; IEEE 754扩展精度   long double,即80位填充到内存中的16个字节,有64个   位尾数,没有隐含位,可以得到19.26十进制数   数字。这是长双倍的几乎通用标准   多年来,但事情已经开始发生变化。

     

较新的128位四精度格式有112个尾数位加上一个   隐含位,可以得到34个十进制数字。 GCC将此实现为   __float128类型和(如果内存服务)编译器选项   设置长双倍。

就个人而言,如果我被要求使用我们自己的pi定义,我会写这样的东西:

#ifndef M_PI
#define PI 3.14159265358979323846264338327950288419716939937510
#else
#define PI M_PI
#endif

如果最新的C标准支持更宽泛的浮点原语数据类型,那么它几乎可以保证数学库中的常量将被更新以支持它。

<强>参考

  1. 更精确的浮点数据类型比双倍?,访问次数2014-03-13,<https://stackoverflow.com/questions/15659668/more-precise-floating-point-data-types-than-double>
  2. C中的数学常数PI值,访问日期2014-03-13,<https://stackoverflow.com/questions/9912151/math-constant-pi-value-in-c>

答案 1 :(得分:4)

宏定义中的位数几乎肯定不会对运行时性能产生任何影响。

宏扩展是文本的。这意味着,如果你有:

#define PI 3.14159... /* 50 digits */

然后,只要您在可以看到该定义的代码中引用PI,就好像您已写出3.14159...

C只有三种浮点类型:floatdoublelong double。大小和精度是实现定义的,但它们通常是32位,64位,宽度大于64位(long double的大小通常在系统与系统之间的变化比其他两个大不相同。)< / p>

如果在表达式中使用PI,它将被评估为某种特定类型的值。事实上,如果文字上没有L后缀,则其类型为double

所以如果你写:

double x = PI / 2.0;

就像你写的那样:

double x = 3.14159... / 2.0;

编译器可能会在编译时评估除法,生成类型为double的值。文字中的任何额外精度都将被丢弃。

要看到这一点,您可以尝试编写一个使用PI宏并检查汇编列表的小程序。

例如:

#include <stdio.h>

#define PI 3.141592653589793238462643383279502884198716939937510582097164

int main(void) {
    double x = PI;
    printf("x = %g\n", x);
}

在我的x86_64系统上,生成的机器代码没有引用完整的精度值。与初始化相对应的指令是:

movabsq $4614256656552045848, %rax

其中4614256656552045848是一个64位整数,对应于尽可能接近3.141592653589793238462643383279502884198716939937510582097164的数字的二进制IEEE双精度表示。

我系统上实际存储的浮点值恰好是:

3.1415926535897931159979634685441851615905761718750000000000000000

其中只有大约16位十进制数字。