0.445を小数第2位で丸めるとき、次の結果は0.44になります。
Math.Round(0.445,2); //結果:0.44
これはC#が"最近接偶数丸め"(Bankers' Rounding) を採用しているからです。
具体的には...
・丸め対象の桁が5の場合、四捨五入の結果は偶数になるようにします。(結果的に五捨六入)
・0.445 → 0.44(0.44 が偶数なのでこちらに丸める)
・0.455 → 0.46(0.46 が偶数なのでこちらに丸める)
解決策:MidpointRounding.AwayFromZeroを使う
double value = 0.445;
double rounded = Math.Round(value, 2, MidpointRounding.AwayFromZero);
Console.WriteLine(rounded); // 出力: 0.45
でも、dubleだと結果が異なる場合がある。
この場合、decimalを使う
double value = 70.445;
double rounded = Math.Round(value, 2, MidpointRounding.AwayFromZero);
Console.WriteLine(rounded); // 出力: 70.44
decimal value = 70.445m;
decimal rounded = Math.Round(value, 2, MidpointRounding.AwayFromZero);
Console.WriteLine(rounded); // 出力: 70.45
このような現象が起こる原因は0.445は2進数で表すと無限になるため。
doubleが2進数の浮動小数点でdecimalが10進数の固定小数点なので、誤差を許容しないときはdecimalを使う。
例えば、計算速度は劣るが、計算誤差は桁あふれを除いて無いため金融ではこの型が用いられる。