Math.Roundを使用しようとしていますが、得られる結果は期待したものではありません。次の数字が5で、その後に他の数字を入れることができない場合でも、丸められることがわかりました。
Assert.AreEqual<double>(4d, Math.Round(4.5)); // Pass
Assert.AreEqual<double>(5d, Math.Round(4.6)); // Pass
Assert.AreEqual<double>(6d, Math.Round(5.5)); // Pass
Assert.AreEqual<double>(4d, Math.Round(4.500001)); // Fail - 5
Assert.AreEqual<double>(4d, Math.Round(4.45)); // Pass
Assert.AreEqual<double>(4.4, Math.Round(4.45, 1)); // Pass
Assert.AreEqual<double>(4.4, Math.Round(4.450001, 1)); // Fail - 4.5
Decimal.Roundの動作も同じです。
Assert.AreEqual<decimal>(4m, Decimal.Round(4.500001m)); // Fail - 5
Assert.AreEqual<decimal>(4.4m, Decimal.Round(4.450001m, 2)); // Fail - 4.5
MidpointRoundingで説明されているように、丸めは、丸め先の小数点以下の桁数だけを考慮に入れるべきではありませんか?
丸め操作は、暗黙的または指定された精度を持つ元の数値を取ります。その精度に 1 を加えた次の桁を調べます。元の数値と同じ精度で最も近い数値を返します。