为什么存在 M_PI_2、M_PI_4、M_1_PI 和 M_2_PI?

Why do M_PI_2, M_PI_4, M_1_PI, and M_2_PI exist?

我明白为什么我们在标准中有这个 headers:

#define M_PI       3.14159265358979323846   // pi

但是,我认为拥有这些并没有多大好处:

#define M_PI_2     1.57079632679489661923   // pi/2
#define M_PI_4     0.785398163397448309616  // pi/4
#define M_1_PI     0.318309886183790671538  // 1/pi
#define M_2_PI     0.636619772367581343076  // 2/pi

在实际代码中使用这些代替M_PI/2M_PI/41/M_PI2/M_PI有什么优势吗?(2020 年及以后?)

spelled-out 表达式不是更具可读性吗?


我真的要问几个原因。

首先,有一天我不小心混淆了 M_PI_2M_2_PI(甚至可能是 2 * M_PI)。花了一段时间才弄清楚出了什么问题,然后又花了一段时间才找出根本原因。仍然认为 M_PI_2M_2_PI 的意思不是很明显,如果您只是阅读使用它们的代码而没有看到定义。我为什么要记住这样的东西?那么,可以肯定地说使用这些定义实际上是 anti-pattern 会降低代码的可读性吗?

其次,having these definitions available may still be an issue, e.g. in Windows (Visual C++)。与其定义所有这些,我更愿意只定义 M_PI,然后在代码中说 M_PI/2 而不是 M_PI_2。有什么我想念的吗?

因为 2 和 4 是 2 的幂,所以 M_PI_2M_PI_4 确实是多余的并且 100% 等同于 M_PI/2M_PI/4。但是,M_1_PI 不一定等同于 1/M_PI;后者有两个舍入(pi 的近似值,然后是不精确的除法)而不是只有一个(1/pi 的近似值)。