無限に続く計算を途中で打ち切ることで生じる誤差。テイラー展開の項数を減らすと近似が粗くなります。
コンピュータは無限回の計算はできないので、本来無限に続く計算を途中で止める必要があります。 この「途中で止める」ことによって生じるズレが打切り誤差です。 身近な例でいえば、円周率 3.14159265... を「3.14」で止めて使うのと同じです。止めた先の 0.00159265... が打切り誤差にあたります。
たとえば sin(x) を正確に求めるには無限個の項を足す必要がありますが、実際には3項や5項で打ち切ります。 打ち切った後ろの項の合計が誤差になるわけです。 つまり、項数を増やせば増やすほど打切り誤差は小さくなる一方、計算時間は増えます。
上のツールで項数スライダーを動かすと、打切り誤差がどう変化するか確認できます。 項数を1→3→5と増やしたとき、近似曲線が真の曲線にどれだけ近づくかを観察してみてください。
打切り誤差の根本原因は、コンピュータが扱えるのは有限回の演算だけであるにもかかわらず、sin・cos・exp・log・π などを正確に求める計算は本質的に無限級数(無限和)や無限反復を必要とする点にあります。どこかで「無限を有限に切り落とす」必要があり、その切り落とした分が誤差として残ります。
最も身近で頻出するのがテイラー展開です。テイラー展開は、sin や cos などの複雑な関数を足し算・引き算・掛け算だけの式(多項式)で近似する手法で、ある点(通常 x=0)の周りで関数の値を多項式で表現します。 コンピュータは四則演算が得意なので、複雑な関数を多項式に変換することで高速に計算できるようになります。
たとえば sin(x) のテイラー展開は次のようになります:
・第1項: x(直線で近似。x が小さいとき sin(x) ≈ x)
・第2項: -x3/3!(= -x3/6 を引いて、曲がり具合を補正)
・第3項: +x5/5!(= +x5/120 を足して、さらに精度を上げる)
項を追加するたびに精度が上がり、無限個の項を使えば完全に一致します。
上のチャートで項数を 1→3→5 と増やしてみてください。近似曲線(青い実線)が真の曲線(灰色の破線)にどんどん近づいていく様子が分かります。 特に1項だけのとき、sin(x) が単なる直線 y=x で近似されることに注目してください。
sin(π/4) ≈ 0.7071 を具体的な数値で見てみましょう。1項だけ(y = x = 0.7854)だと真の値 0.7071 との誤差は約 0.078、つまり約11%もずれています。3項(x - x3/6 + x5/120)まで使うと 0.70711 となり、誤差は 0.00045 に激減します。
さらに5項まで使うと誤差は 10-7 以下になり、電卓と同じ精度が得られます。 つまり、わずか5回の四則演算で sin 関数を小数点以下6桁まで正確に近似できるのです。 これがテイラー展開の実用的な威力です。
ただし、x = 0 付近では少ない項数でも精度が高い一方、x が大きくなるほど多くの項数が必要になります。 上のツールで x のスライダーを 0 付近 → π付近に動かし、同じ項数でも位置によって精度が大きく変わることを確認してみてください。
まとめると項数と誤差の関係はトレードオフです。項数を増やすほど打切り誤差は小さくなる一方、計算時間(演算回数)は増えます。実務では「許容誤差を満たす最小の項数」を選ぶのが鉄則で、その指標として「次の項の絶対値が誤差の上限のおおよその目安になる」(テイラー級数が交代級数なら厳密に上限)という性質がよく使われます。
| 打切り誤差 | 丸め誤差 | |
|---|---|---|
| 原因 | 無限級数を有限で打ち切る | ビット数が有限で四捨五入 |
| 発生場面 | テイラー展開、数値積分 | 浮動小数点演算全般 |
| 対策 | 項数を増やす | 倍精度(64bit)を使う |
| 0にできるか | 理論上は可能(項数→∞) | 0にはできない |
打切り誤差は「計算を途中で止める」ことで生じ、丸め誤差は「桁数が足りなくて四捨五入する」ことで生じます。 つまり、打切り誤差はアルゴリズムのレベルの問題で、丸め誤差はハードウェア(ビット数)のレベルの問題です。
打切り誤差は項数を増やせば理論上0にできますが、丸め誤差はビット数を増やしても完全には0にできません(0.1は何ビットあっても2進数で正確に表現できない)。 原因も対策も異なるので、この2つは区別して理解しておくことが大切です。
同じ5項でも、関数によって収束の速さが大きく異なります。sin(x) や cos(x) は各項の分母に階乗(3!, 5!, 7!...)が入るため、項が急速に小さくなり、少ない項数でも高精度です。 一方、ln(1+x) は分母が 1, 2, 3, 4... と緩やかにしか増えないため、収束が遅く多くの項数が必要です。
具体的には、x=1 のとき sin(1) は5項で誤差 10-8 程度ですが、ln(2) は5項でも誤差 0.063 と約10%もずれています。 収束が速い関数ほど少ない計算量で高い精度が得られるため、実用上は収束が速い形に式を変形するテクニックも使われます。
上のツールで関数を切り替えて、同じ項数でも精度が大きく違うことを確認してみてください。 特に ln(1+x) で x=1 のときは20項使ってもなかなか収束しない様子が観察できます。
CPUは基本的に加算・乗算などの四則演算しかできません。sin(x) や cos(x) のような超越関数を直接計算する回路は持っていないのです。 そこでCPU内部ではテイラー展開に似た多項式近似を使い、四則演算の組み合わせでこれらの関数を計算しています。
たとえば倍精度(64ビット)で sin(x) を計算する場合、テイラー展開で約10項使えば 10-16 の精度が得られ、倍精度の仮数部52ビット(約15桁)を十分カバーできます。 「十分な精度が得られる項数」で打ち切ることで、高速かつ実用上十分な精度の計算を実現しています。
実際のCPUでは、テイラー展開そのものではなく、より効率の良いチェビシェフ近似やCORDIC アルゴリズムが使われることもあります。 しかしいずれも「無限を有限で近似する」という基本原理は同じで、打切り誤差と向き合っています。 プログラムでMath.sin(x)と書くだけで結果が返ってくるのは、このような近似計算がCPU内部で瞬時に行われているからです。