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


コメント