C#で小数点以下の計算時にdouble型を使用してはいけない理由

この記事を書いたチーム:frontier
C#で小数点以下の計算時にdouble型を使用してはいけない理由

なぜC#で小数点以下の精度の高い計算が要求される場合にdouble型を使用してはいけないのか

【エンジニア募集中】フルリモート可◎、売上/従業員数9年連続UP、平均残業8時間、有給取得率90%、年休124日以上 etc.  詳細はこちらから>

C#で基本的に使用される数値型はint型やlong型やdouble形になると思いますが、

このうち浮動小数点数型はdouble形になります。

しかしdouble型は実は完全に正確ではなく、数値の誤差が発生してしまう可能性があるのです。

なぜ数値の誤差が発生してしまうのか?

double型は、浮動小数点数型で64ビットの精度を持っています。

この浮動小数点数が2進数で表現されているため、10進数で表現しようとした際に完全に正しく表示することが難しい場合が存在します。

例を挙げると、10進数で表現するところの0.1です。

この0.1は2進数では0.000110011001100110011…となり、0011がループし無限小数となってしまうため、誤差が生じてしまうのです。

小数点以下の精度の高い計算が要求される場合に使用すべき型

double型を使用しないとなると、この場合に使用すべき型はdecimal型になります。

では、なぜdecimal型の方が正確な値を出力できるのでしょうか?

 

decimal型は、固定小数点数型で128ビットの精度を持っています。

double型は2進数で表現されていますが、decimal型は10進数で表現されます。

そのため、小数点以下の計算でも誤差が発生せず正確な計算ができるのです。

decimal型のデメリット

ここまで、decimal型の優れている点を記載してきましたが、デメリットもあります。

そのデメリットとは、double型に比べてdecimal型の方が計算速度が遅いということです。

なので、大量の計算を行う場合には注意が必要になります。

その他にも、固定小数点数型のため数値表現の限界があるので、使用する数値の範囲によっては正確な計算ができなくなる場合があります。

上記のデメリットがありますので、安易にdecimal型を使用するのではなく、使用用途によって使い分ける必要があります。

まとめ

以前精度の高い計算が要求されるような業務に関わっていた際に、double型を使用して不具合が発生したことがありました。

ぱっと見何も間違えていないのに、なぜか結果が違ってくるので原因を特定するのにかなり苦戦して時間を取られた記憶がありますので、不具合が発生する前に、そもそも小数点以下の精度が高い計算が必要だと分かっている場合には、double型ではなくdecimal型を使用することを推奨します。

【エンジニア募集中】フルリモートも◎(リモート率85.7%)、平均残業8時間、年休124日以上、有給取得率90% etc. 詳細はこちらから>

Smallitのサービス