C#中的十进制类型的自定义舍入

red*_*zon 5 c# rounding

伙计们,我正在写一个四舍五入的方法.输入是十进制类型(保证四位小数).舍入规则是忽略0.005或更小,即查看小数点后三位 - 如果它是<= 5,则向下舍入向上舍入.一些用例:82.3657 - > 82.36,82.3667 - > 82.37,82.5967 - > 82.60,82.9958 - > 82.99,82.9968 - > 83.00有什么好主意吗?我按如下方式解决了这个问题.

private decimal CustomRound(decimal x)
{
   decimal rX = Math.Truncate(x * 100) / 100;
   decimal x3DecPlaces = Math.Truncate(x * 1000) / 1000;
   decimal t = (x3DecPlaces * 1000) % 10;
   if (t >= 6)
      rX = rX + 0.01m;
   return rX;
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 7

我不相信有任何内置的东西,因为这是一个非常不寻常的要求(例如1.3358接近1.33而不是1.34的想法很奇怪).您的代码看起来合适.

编辑:你不能MidpointRounding用来获得你想要的效果,因为你开始四舍五入的点不是中点 - 它是(比方说)1.336而不是正常的1.335.只有1.335被视为1.33和1.34之间的中点,因为这中点.你以一种不同寻常的方式有效地在这里进行了偏向.

你甚至不能截断到三个DP然后使用MidpointRounding,因为没有"朝向零"模式.

一个稍微奇怪的选择是自己有效地执行偏见:

private static decimal CustomRound(decimal x)
{
    return decimal.Round(x - 0.001m, 2, MidpointRounding.AwayFromZero);
}
Run Code Online (Sandbox Code Playgroud)

所以它将82.3657视为82.3647并将其舍入为82.36; 它会对待82.3667和82.3657并将其四舍五入为82.37,它会将82.5967视为82.5957并将其舍入为82.60等.我认为这样做你想要的 - 但仅限于正值.您需要准确计算出负值所需的行为.

无论你做什么,你都需要非常清楚地记录下来:)

作为一个偏好的问题,我会使用decimal.Truncate而不是Math.Truncate,只是为了更清楚地表明一切都是用小数来完成的.