.Net 小数点四舍五入

.Net decimal rounding oddities

我很难理解为什么 .NET 中的 Math.Round 函数(使用框架 4.5)以某种方式运行:

Math.Round(21.4451m, 2, MidpointRounding.ToEven) // 21.45

当我将最后一个小数位设置为 0 来调用相同的方法时:

Math.Round(21.4450m, 2, MidpointRounding.ToEven) // 21.44

谁能解释一下为什么第一个例子的最后一位小数是 1 或更多时四舍五入结果是 21.45?

我需要知道,因为我正在尝试在 SQL 服务器中编写一个与 .NET 框架正在执行的操作完全匹配的算法(因为 SQL 服务器使用算术舍入)。

您四舍五入到小数点后两位。你正在使用 ToEven:

When a number is halfway between two others, it is rounded toward the nearest even number.

任何 大于 21.445 (>21.445) 的数字将四舍五入为 21.45

任何 小于或等于 21.445 (<=21.445) 的数字将四舍五入为 21.44。

Math.Round(21.44500001m, 2, MidpointRounding.ToEven); //>21.445 therefore 21.45
Math.Round(21.44500000m, 2, MidpointRounding.ToEven); //=21.445 therefore 21.44
Math.Round(21.44499999m, 2, MidpointRounding.ToEven); //<21.445 therefore 21.44

它工作正常。 ;)

为了获得与 SQL 中相同的 ROUND 行为,请使用 AwayFromZero。

SELECT ROUND(21.4451, 2), ROUND(21.4450, 2), ROUND(21.4449, 2)
--less decimal casting, yields:
--     21.4500            21.4500            21.4400

Math.Round(21.44500001m, 2, MidpointRounding.AwayFromZero); //21.45
Math.Round(21.44500000m, 2, MidpointRounding.AwayFromZero); //21.45
Math.Round(21.44499999m, 2, MidpointRounding.AwayFromZero); //21.44