如何在.NET中自定义Math.Round的行为?

时间:2011-04-15 06:58:25

标签: .net vb.net math rounding

我必须使用遵循此行为的圆方法:

7.00 - >圆 - > 7
7.50 - >圆 - > 7
7.51 - >圆 - > 8

我尝试使用Math.Round,但它有点不同。

Dim val As Decimal = 7.5
Dim a As Decimal = Math.Round(val, 0) ' -> 8
Dim b As Decimal = Math.Round(val, 0, MidpointRounding.AwayFromZero) ' -> 8
Dim c As Decimal = Math.Round(val, 0, MidpointRounding.ToEven) ' -> 8

如何实现舍入逻辑?

4 个答案:

答案 0 :(得分:2)

您可以从总数中减去0.01,然后拨打Math.round(..)

double d = 7.5;
double result = Math.Round(d - 0.01);

如果数字为负数,则必须执行以下操作才能获得相同的结果:

double d = -7.5;
if (d < 0)
{
    double tmp = Math.Abs(d) - 0.01;
    double result = -Math.Round(tmp);
}

工作示例here

但请注意,此行为可能您想要的内容,如其他几个人所述。

如果你阅读了这个答案的评论,@ alex zhevzhik也注意到如果输入的小数超过2,这个解决方案将会失败。

答案 1 :(得分:1)

Midpoint无法提供适当的功能。在备注中查看表格中的第一行和第三行。如果将val更改为6.5,则会获得预期的行为,但不会使用7.5。

您应该编写自己的舍入实现。

Javed Akram的实施很好,但是负数完全错误。 由于你没有提供负数舍入的详细信息,我认为标准的四舍五入。此外,您应该考虑“特殊”双重值:

static class Helper
{
    public static double Round(double val)
    {
        if (Double.IsNaN(val) || Double.IsNegativeInfinity(val) || Double.IsPositiveInfinity(val))
        {
            return val;
        }

        var decimalPart = Math.Truncate(val);
        if (val >= 0)
        {
            if (val - decimalPart <= 0.5)
            {
                return Math.Floor(val);
            }
            else
            {
                return Math.Ceiling(val);
            }
        }
        else
        {
            return Math.Round(val, 0);
        }
    }
}

答案 2 :(得分:0)

嗯,我不知道是否有一个Math.Round方法可以做你想要的,但我认为你需要编写自己的方法。因为通常情况下,7.5将四舍五入为8,除非我忘记在高中学到的一切。

答案 3 :(得分:0)

    Dim i As Decimal
    Dim j As Integer
    Dim k As Decimal

    i = 7.51
    k = i - Math.Truncate(i)  'decimal part of number

    If (k <= 0.5) Then
        j = Math.Floor(i)
    Else
        j = Math.Ceiling(i)
    End If