为什么math.h定义pi,pi / 2,2 / pi而不是2 * pi?

时间:2012-11-17 00:55:23

标签: c math.h

这是一个非常简单的问题:为什么pi,pi / 2,pi / 4,1 / pi和2 / pi有predefined constants但是2 * pi没有?背后有更深层的原因吗?

这个问题不是关于整个pi vs tau debate。我想知道是否有技术原因来实现某些常量而不是其他常量。我可以想到两种可能性:

  1. 避免舍入错误。
  2. 避免可能更昂贵的运行时划分。

2 个答案:

答案 0 :(得分:6)

2 * M_PI难以写吗?

很明显,曾经有一段时间,当人们担心可能不会进行不断折叠和分割的简单编译器过于昂贵时,实际上有一个恒定的PI / 2而不是冒运行时划分的风险是有意义的。在我们的现代世界中,人们可能只会定义M_PI并将其称为一天,但其他变体仍可用于向后兼容。

答案 1 :(得分:3)

这只是我的猜测。

我认为这些常量与数学库中不同函数的实现有关:

ck@c:~/Codes/ref/glibc/math$ grep PI *.c
s_cacos.c:  __real__ res = (double) M_PI_2 - __real__ y;
s_cacosf.c:  __real__ res = (float) M_PI_2 - __real__ y;
s_cacosh.c:                    ? M_PI - M_PI_4 : M_PI_4)
...
s_clogf.c:      __imag__ result = signbit (__real__ x) ? M_PI : 0.0;
s_clogl.c:      __imag__ result = signbit (__real__ x) ? M_PIl : 0.0;
ck@c:~/Codes/ref/glibc/math$ 

M_PIM_PI_2M_PI_4经常出现,但没有2.0 * M_PI。所以对于Hanno的原始问题,我认为MvanGeest是对的 - 2π不是那么有用,至少在实施libm时是这样。

现在关于M_PI_2M_PI_4,他们的存在是合理的。 GNU C库的documentation表明“这些常量来自Unix98标准,并且也可以在4.4BSD中获得”。那时编译器并不那么聪明。键入M_PI/4而不是M_PI_4可能会导致不必要的分割。虽然现代编译器可以对其进行优化(gcc自2008年起使用mpfr,因此即使正确完成舍入),使用数字常量仍然是编写高性能代码的更便携方式。