朝会発表テーマ

浮動小数点型の誤差

1. 事例

ある処理で金額を合計したとき、
「2057.3 + 3196.9 = 5254.200000000001」となり、計算結果が合わなかった。

2. 原因

計算に使用した変数の型が「2進数」を使用した浮動小数点数型(C#ではfloat, double型)だったため。2進数は小数を正確に表現することが難しい。

  例: 0.1
0.1を2進数に直すと「0.0001100110011…」となり「0011」が循環する。
    参考:基本情報技術者講座 10進数から2進数への変換方法
http://www.it-license.com/cardinal_number/DecimalToBinary.html

 浮動小数点数型に入れた場合、あるところで丸められる。
「0.0001100110011001100110011001100110011001100110011001101」

これは10進数では
   「0.10000000000000000555111512…」となり、「0.1」ではない

3. 対応

・10進数の浮動小数点数型(C#ではdecimal型)を使用する。
10進数なので小数を正確に表現できる。
ただし、パフォーマンスが悪い、格納できる値の範囲が小さいという欠点がある。

  ・整数に直してから計算する
10倍する、四捨五入、切り上げ、切り捨て

参考

 DOBON.NET 小数(浮動小数点数型)の計算が思った結果にならない理由と解決法
 https://dobon.net/vb/dotnet/beginner/floatingpointerror.html

コメント