これは非常に単純な質問です: pi、pi/2、pi/4、1/pi、および 2/pi には定義済みの定数があるのに、2*pi には定義されていないのはなぜですか? その背後にはもっと深い理由がありますか?
この質問は、パイ対タウの議論全体に関するものではありません。特定の定数を実装し、他の定数を実装しない技術的な理由があるかどうか疑問に思っています。次の 2 つの可能性が考えられます。
- 丸め誤差の回避。
- よりコストがかかる可能性のあるランタイム分割を回避します。
これは非常に単純な質問です: pi、pi/2、pi/4、1/pi、および 2/pi には定義済みの定数があるのに、2*pi には定義されていないのはなぜですか? その背後にはもっと深い理由がありますか?
この質問は、パイ対タウの議論全体に関するものではありません。特定の定数を実装し、他の定数を実装しない技術的な理由があるかどうか疑問に思っています。次の 2 つの可能性が考えられます。
2*M_PI を書くのは難しいですか?
真剣に、むかしむかし、単純なコンパイラーが定数の折りたたみを行わない可能性があり、除算が法外に高価であると人々が心配していたとき、実行時の除算の危険を冒すよりも、実際には定数 PI/2 を使用する方が理にかなっていました。現代の世界では、おそらく M_PI を定義するだけで終わりですが、他のバリアントは下位互換性のために存続しています。
これは私の推測です。
これらの定数は、数学ライブラリのさまざまな関数の実装に関連していると思います。
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_PI
、M_PI_2
、およびM_PI_4
かなり頻繁に表示されますが、ありません2.0 * M_PI
。したがって、Hanno の最初の質問に対しては、MvanGeest が正しいと思います --- 2π は、少なくとも実装においてはそれほど有用ではありませんlibm
。
M_PI_2
とについてM_PI_4
は、それらの存在は十分に正当化されます。GNU C ライブラリのドキュメントは、「これらの定数は Unix98 標準に由来し、4.4BSD でも利用可能であった」ことを示唆しています。当時、コンパイラはそれほど賢くありませんでした。M_PI/4
の代わりに入力M_PI_4
すると、不要な分割が発生する場合があります。最新のコンパイラはそれを最適化できますが (gcc は 2008 年から mpfr を使用しているため、丸めも正しく行われます)、数値定数を使用することは、高性能コードを記述するためのより移植性の高い方法です。