数値計算で型による誤差

2進数と10進数では内部の数値の扱い型が違います

これを認識していないと思わぬバグを生むことがあります

サンプル

次のコードを見てください

var price1 = 0.1 + 0.1 + 0.1;
var price2 = 0.1m + 0.1m + 0.1m;

Console.WriteLine(price1);
Console.WriteLine(price2);

このコードは、浮動小数点数と十進数の計算の違いを示しています。この違いは、数値を表現する際の精度と内部表現に関連しています。具体的には、price1price2 の計算と出力を行っていますが、それぞれ異なる数値型を使用しています。

  1. var price1 = 0.1 + 0.1 + 0.1;:
    • ここで使用されている 0.1 は、通常の浮動小数点リテラルです。これは double 型(倍精度浮動小数点数)で扱われます。
    • 浮動小数点数は、二進数で近似値を表現します。これは一部の値(特に10進数の小数)が正確に表現できないことを意味します。その結果、0.1 + 0.1 + 0.1 の計算は 0.3 にならず、非常に近い値になりますが、正確な 0.3 ではありません。
    • Console.WriteLine(price1); はこの近似値を出力します。
  2. var price2 = 0.1m + 0.1m + 0.1m;:
    • ここで使用されている 0.1m は、十進数リテラルです。m サフィックスは、数値が decimal 型(十進数)であることを示します。
    • decimal 型は、金融計算など精度が重要な場面で使用され、より高い精度で10進数の値を表現できます。
    • 0.1m + 0.1m + 0.1m の計算は、正確に 0.3 となります。
    • Console.WriteLine(price2); はこの正確な値を出力します。

結果として、このコードは浮動小数点数(double)と十進数(decimal)の扱いの違いを明確に示しており、特に金融計算においては decimal 型が好ましいことを示唆しています。price1 の出力は 0.3 に非常に近い値になりますが、price2 の出力は正確に 0.3 になります。

参考

C#,学習

Posted by hidepon