GCCが実行時に固定値で算術演算を実行するのか、それとも答えに設定するのか疑問に思っています.
const float halfPi = M_PI/2;
方程式を「煮詰めて」設定しますか
const float halfPi = 1.57079;
それとも演算は実行時に任せますか?
GCCが実行時に固定値で算術演算を実行するのか、それとも答えに設定するのか疑問に思っています.
const float halfPi = M_PI/2;
方程式を「煮詰めて」設定しますか
const float halfPi = 1.57079;
それとも演算は実行時に任せますか?
ええと...積分について話している場合、答えは明確なイエスです(一般的な用語である定数フォールディングの下で)。時間のかかる計算でもコンパイル時に実行できます...これは、テンプレートの非型パラメーターの評価と (現在)constexpr
変数に実際に必要です。
浮動小数点表現の場合、計算が少し複雑になるとすぐに、少し複雑になります。問題は、異なるサイズ (したがって精度) の浮動小数点表現は、同じ基本入力に対して異なる結果をもたらすことです。
理由を理解するために、float
精度が最大で 5 桁であるとします。
5.0000 + 0.00001
-> 5.00001
-> 5.0000 (truncation to 5 digits)
5.0000 + 0.00001 + ... + 0.00001 (10 times)
-> 5.0000 + 0.00001 + ... + 0.00001 (9 times)
-> 5.0000 + 0.00001 + ... + 0.00001 (8 times)
-> ...
-> 5.0000
意外…ですよね?コンパイルが実行時に行われる場合、結果はレジスタ (より大きなビット幅) が使用されているかどうかによって異なる場合があります。
したがって、定数の折りたたみが発生するかどうかは、使用する最適化フラグのセットに依存する可能性があります。たとえば、gccの場合、これは(実際にはわかりません)によって制御される可能性があります-freciprocal-math
。コンパイラは確かにそれを行うことができますが、(無意識のうちに) そうしないように指示している可能性があるためです。
したがって、これをテストする唯一の確実な方法は、コンパイラの出力を確認することです。オブジェクトコードを検査するか、コンパイラにアセンブリを発行するように依頼するかのいずれかです。また、使用するオプションのすべての組み合わせについて、この出力を確認する必要があります。