LeoAndo / java-training

0 stars 0 forks source link

浮動小数点数の計算の誤差について #60

Open LeoAndo opened 3 years ago

LeoAndo commented 3 years ago

丸め誤差

コンピュータが「表現できる数の範囲」(有効桁)を超えてしまった際に、「四捨五入」や「切り上げ」「切り捨て」などを行い有効桁以降の値を捨てることにより生じる誤差のこと。

例えば、0.3を2進数にすると、「0.010011001100110011001100110011001100110011001100110011...」のような循環少数に対して、「表現できる数の範囲」(有効桁)が24ビットの場合(float型の有効桁数)、「0.0100110011001100110011」と有効桁以降の部分を捨てます。その結果、正しい結果との間に誤差が発生します。この時に発生する誤差が「丸め誤差」。

対策

BigDecimal を使って計算する サンプル

LeoAndo commented 3 years ago

桁落ち

値がほぼ等しく丸め誤差を持つ数値の差を求めた時に、有効数字が大きく減ることによって生じる誤差のことです。 有効桁数で失われた桁を0で埋めるため、計算誤差が生まれる。

対策

BigDecimalを使って計算する サンプル サンプル2

LeoAndo commented 3 years ago

情報落ち

絶対値が大きく違う数字(大きな値と小さい値)の加減算を行った際に、小さい値の情報が無視されてしまうことによって生じる誤差のこと。 浮動小数点数での仮数(有効桁)には桁数の制限があるため、仮数で表現できる範囲を越す数字は無視される。

対策

BigDecimalを使って計算する、もしくは、大きさの近い数字同士で計算していく。(計算の順序を変える) サンプル

LeoAndo commented 3 years ago

打ち切り誤差

打ち切り誤差とは、コンピュータの計算処理を途中で打ち切ることにより発生する誤差のこと。 例えば「10 ÷ 3 = 3.333333...」のような無限に続く計算を行う場合、コンピュータは途中で計算を打ち切る。 その結果、正しい結果との間に誤差が発生します。この時に発生する誤差が「打ち切り誤差」。

対策

BigDecimalを使って計算する サンプル

LeoAndo commented 3 years ago

オーバーフロー / アンダーフロー

オーバーフロー: 浮動小数点の場合には指数部の大きさが上限値よりも大きくなった場合にそれ以上大きな値を表すことができずオーバーフローとなる。オーバーフローすると計算結果は、Infinityになる

アンダーフロー: 浮動小数点数において、値の絶対値が小さくなりすぎ(小数点以下の0の桁数が長くなりすぎ)て正しく値を表現できなくなる現象を「アンダーフロー」(underflow)という。指数部が下限値より小さくなることで発生し、0に置き換えられてしまうことで除算や乗算の結果が大きく狂うといったことが起きる。アンダーフローすると計算結果は0.0になる.

サンプル

LeoAndo commented 3 years ago

リンク集

https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Double.html https://ja.wikipedia.org/wiki/IEEE_754 https://medium-company.com/%E4%B8%B8%E3%82%81%E8%AA%A4%E5%B7%AE-%E6%89%93%E3%81%A1%E5%88%87%E3%82%8A%E8%AA%A4%E5%B7%AE-%E6%A1%81%E8%90%BD%E3%81%A1-%E6%83%85%E5%A0%B1%E8%90%BD%E3%81%A1-%E9%81%95%E3%81%84/