(2020.2.13追記) 2020.2.10に投稿したときはプログラムに間違いがあって大嘘を書いていました。ごめんなさい。
はじめに
任意の角度の三角関数を加法定理で1度ずつなどの刻みで計算した時の振る舞いが気になったので(※現実逃避)実際に試してみました。
復習ですが、三角関数の加法定理は下記のようになります。
\sin(\alpha + \beta) = \sin(\alpha)\cos(\beta) + \cos(\alpha)\sin(\beta) \\
\cos(\alpha + \beta) = \cos(\alpha)\cos(\beta) - \sin(\alpha)\sin(\beta) \\
これを利用して、$\sin, \cos$のそれぞれ0°と1°の値のみを用いて任意の角度(整数)の三角関数の値を求めてみました。
実験
コードはここ(github)におきました。
コンパイルと実行は、下記で通るはずです。
$ make all # コンパイル
$ make run # 実行
結果
角度の刻みを少し変えながら、0°から3600°まで試してみました。
下記のグラフはいずれも紫・緑の線がライブラリの返した値(凡例:std::sin, std::cos)、水色・オレンジの点(凡例: sin, cos)が加法定理で計算した値です。
こうしてみると、1度刻みで3600°($20\pi$)まで計算したとしても、ほぼ完全に線が重なっているように見えます。
1°刻みで計算
3°刻みで計算
10°刻みで計算
ライブラリ関数との差のプロット
上記の結果について、標準ライブラリ(cmathのstd::sin())が返す値との差の絶対値をプロットしたものが下記になります。
このように拡大してみるとやはり刻み幅は広い場合($10^\circ$;水色の線)の方が、刻みが細かい場合($1^\circ$; 紫の線)よりは差が小さいことがわかります。
同時に、この差ですが一次関数に$\sin$関数を掛けたような形($y=a\theta\sin(\theta)$; aは定数)になるようです。どうしてこのような形になるのかはよくわかりません。(標準ライブラリの三角関数の求め方に依存しているのかもしれませんが。。。)
まとめ
とりあえずグラフを書いてみました。
数値計算の誤差の取り扱いに関する知識がないため、これ以上深い議論はできないのですが、思ったより精度があるのだな、と感じた次第です。