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

han*_*nno 21 c math.h

这是一个非常简单的问题:为什么有pi,pi/2,pi/4,1/pi和2/pi的预定义常量,但不是2*pi?背后有更深层次的原因吗?

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

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

Ste*_*non 6

2*M_PI难以写吗?

但是,从某种程度上说,当人们担心可能不会进行不断折叠和分割的简单编译器非常昂贵时,实际上有一个恒定的PI/2而不是冒运行时划分的风险.在我们的现代世界中,人们可能只需要定义M_PI并将其称为一天,但其他变体可用于向后兼容.


小智 4

这只是我的猜测。

\n\n

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

\n\n
ck@c:~/Codes/ref/glibc/math$ grep PI *.c\ns_cacos.c:  __real__ res = (double) M_PI_2 - __real__ y;\ns_cacosf.c:  __real__ res = (float) M_PI_2 - __real__ y;\ns_cacosh.c:                    ? M_PI - M_PI_4 : M_PI_4)\n...\ns_clogf.c:      __imag__ result = signbit (__real__ x) ? M_PI : 0.0;\ns_clogl.c:      __imag__ result = signbit (__real__ x) ? M_PIl : 0.0;\nck@c:~/Codes/ref/glibc/math$ \n
Run Code Online (Sandbox Code Playgroud)\n\n

M_PIM_PI_2、 并M_PI_4经常出现,但没有2.0 * M_PI。因此,对于 Hanno 最初的问题,我认为 MvanGeest 是对的 --- 2\xcf\x80 没有那么有用,至少在实现libm.

\n\n

现在关于M_PI_2M_PI_4,它们的存在是有充分理由的。GNU C 库的文档表明“这些常量来自 Unix98 标准,并且在 4.4BSD 中也可用” 那时的编译器还没有那么聪明。键入M_PI/4“of”M_PI_4可能会导致不必要的除法。尽管现代编译器可以对此进行优化(gcc 自 2008 年以来就使用 mpfr,因此即使舍入也可以正确完成),但使用数字常量仍然是编写高性能代码的更便携的方式。

\n