三角関数は不要
インテルとAMDのCPUでの話です。
インテルとAMDのCPUには,三角関数を数値的に計算するための命令が備えられていますが,その結果は正しくありません。たとえば,CPUの命令FCOSの結果とstd::cosでソフトウェア的に計算した結果を比べると,後者の方が真の値に近くなります。
再現のためのコード(FCOSを使う部分だけインラインアセンブラを使っています。)
Core i5 6600とg++ 4.8.4で試した結果はこんな感じです。
x = 0.98233490762409514385
c1 = fcos(x) = 0.55508189550073283591
c2 = std::cos(x) = 0.55508189550073294694
c = mp::cos(x) = 0.555081895500732891425063460345544265145531916268
abs(c - c1) = 5.5512e-17
abs(c - c2) = 5.551e-17
c1 is better: 0
c2 is better: 25
total: 100000
(その正しさをどうやって確かめるのかという問題はありますが)Boost.Multiprecisionで計算した結果と比較すると,命令FCOS
よりstd::cos
の方が正確なようです(Visual Studioの場合はまた違った結果になるようです)。
Pentiumが割り算を間違うといって大騒ぎになったことがありましたが(Pentium FDIV バグ),数値計算はどうせ近似値だからでしょうか,この問題は,ドキュメントに注意書きが追記されただけで,根本的な解決はされないままのようです。
参考:サイン、コサインをインテルの CPU で計算すると少しバグっているらしい
三角関数には、三角関数に実用性を見出せない人を見出せるという実用性があります。重力場の方程式ではおそらくこうはいきません。
— Taro YABUKI (@yabuki) 2015, 8月 28