Skip to content

Latest commit

 

History

History
132 lines (97 loc) · 8.02 KB

File metadata and controls

132 lines (97 loc) · 8.02 KB

数値計算と誤差

計算機を用いた数値計算では,数の表現や計算に伴う誤差が生じる. 以下に,数値計算における誤差の例を示す.

  誤差        説明
桁落ち 値のほぼ等しい数値同士の減算などによって有効数字が失われることによって生じる.
丸め誤差 有限桁数の二進数で実数を表現することによって生じる.
情報落ち 絶対値の大きく異なる数値同士の演算において,絶対値の小さな数値が演算結果に反映されないために生じる.

桁落ち

値のほぼ等しい数値同士の減算では,有効数字が失われる可能性がある.この現象を桁落ちと呼ぶ. 例えば次のような計算を行う場合,

上記を倍精度で計算する場合,程度になるとの値が有効数字の範囲内でほぼ等しくなるため,減算によって有効数字が大きく損なわれる. さらに程度では,減算の結果は0になってしまう. これを避けるためには,値のほぼ等しい数値同士の減算を避ける必要がある. その方法の一つに,次のような分子の有理化がある. これを用いることで,値のほぼ等しい数値同士の減算を避けることが出来る.

以上に基づいて,以下の計算を実装する.

について,

  • x=1e+15を代入して通常通り計算
  • x=1e+16を代入して通常通り計算
  • x=1e+15を代入して有理化して計算
  • x=1e+16を代入して有理化して計算

実行例

x=1e+15       : 1.862645149230957e-8
x=1e+15(有理化): 1.5811388300841893e-8
x=1e+16       : 0.0
x=1e+16(有理化): 5.0e-9

丸め誤差

丸め誤差は,実数を有限の桁数の2進数で表現するために生じる誤差. 10進数の無理数や循環少数,2進数表現で循環少数になる数値を計算機で扱う際に生じる可能性がある. 例えば,10進数の0.1は2進数では次のような循環少数となる.

したがって,10進数の0.1を計算機を扱う場合には必ず丸め誤差を伴うことになる.

上記に従って,0.1を100万回足し合わせた結果を出力し,加算結果が100000と厳密に一致しないことを確かめる.

実行例

result=100000.00000133288

情報落ち

情報落ちは,絶対値の大きく異なる数値同士の演算において,絶対値の小さな数値が演算結果に反映されない現象. 情報落ちが生じる場合の例として,を繰り返し加える計算を考える. これを単純に実装すると,絶対値の小さな数値が演算結果に反映されない. しかし,計算順序を工夫することでこれを回避することが出来る場合がある. 具体的には,はじめに絶対値の小さな値の数値同士を加えてから,あとで絶対値の大きな数値に加えることで,加算結果を反映させることが出来る.

上記にしたがって,を単純に1000万回加算した場合と,はじめにを10000万回加算したあとその結果をに足し合わせた結果を出力し,それぞれの計算結果が一致しないことを確かめる.

実行例

result1=1.0e10
result2=1.00000000001e10

Overflow

あるデータ型で扱える値の範囲を超えた時,オーバーフローという現象が発生する. 例えばjuliaのInt64では,扱える値の範囲はになっている.

実際にjuliaでを型変換なしで出力してオーバーフローが発生することを確認する.

実行例

2^62=4611686018427387904
2^63=-9223372036854775808

Rumpの例題

以下の関数は,数値計算における演算精度についての好ましく無い結果を導くものである.

IBMのメインフレームS/370を用いて,以下の精度で実験を行うと,

  • 単精度(10進約8桁):
  • 倍精度(10進約17桁):
  • 拡張精度(10進約34桁):

という結果を得られ,精度をあげるごとに計算できる桁数が増えているように見えるが,実際の真の値はと,全く違う計算結果が得られていたことがわかった. この関数はRumpの例題として知られており,複数の精度で計算して近い結果が得られていればある程度正しい計算結果を導けているという仮説を覆すものである.

上記に従って,JuliaでFloat64およびBigFloatの演算精度でRumpの例題を計算し,それぞれの計算結果を出力する.

実行例

Float64: -1.1805916207174113e21
BigFloat: -0.8273960599468213681411650954798162919990331157843848199178148416727096930142628

誤差伝播

ある数値計算を行って得られる結果は誤差を伴うことが多々あるが,このような誤差を持った数値を用いて新たな計算を行った結果もまた,当然誤差を持つ.これを誤差の伝播という. ここでは四則演算のうち,加減法について考える. 加減法における誤差伝播には,以下の法則がある.

加減法の誤差伝播

から計算されるの誤差は,次式のように抑えられる.

a=5b=7da=0.1db=0.3として,上記の関係式が成り立つことを確かめる.

実行例

|(a+b)-(a+da)+(b+db)|: 0.3999999999999986<=0.4
|(a+b)-(a-da)+(b+db)|: 0.1999999999999993<=0.4
|(a+b)-(a+da)+(b-db)|: 0.1999999999999993<=0.4
|(a+b)-(a-da)+(b-db)|: 0.3999999999999986<=0.4
|(a-b)-(a+da)+(b+db)|: 0.20000000000000018<=0.4
|(a-b)-(a-da)+(b+db)|: 0.39999999999999947<=0.4
|(a-b)-(a+da)+(b-db)|: 0.39999999999999947<=0.4
|(a-b)-(a-da)+(b-db)|: 0.20000000000000018<=0.4