内置.Net算法,将值舍入到最接近的10个区间

问题描述 投票:61回答:6

如何在C#中将任意值舍入到10个区间?例如,如果我有11,我希望它返回10,如果我有136,那么我希望它返回140。

我可以轻松地手工完成

return ((int)(number / 10)) * 10;

但我正在寻找一种内置算法来完成这项工作,比如Math.Round()。我不想手工做的原因是我不想在我的项目中编写相同或类似的代码,即使是像上面那样简单的东西。

c# math rounding
6个回答
89
投票

类库中没有内置函数可以执行此操作。最接近的是System.Math.Round(),它仅用于将Decimal和Double类型的数字舍入到最接近的整数值。但是,如果使用的是.NET 3.5,则可以使用扩展方法将语句包装起来,这样可以更加干净地使用该函数。

public static class ExtensionMethods
{
    public static int RoundOff (this int i)
    {
        return ((int)Math.Round(i / 10.0)) * 10;
    }
}

int roundedNumber = 236.RoundOff(); // returns 240
int roundedNumber2 = 11.RoundOff(); // returns 10

如果你是针对旧版本的.NET框架进行编程,只需从RoundOff函数中删除“this”,然后像这样调用函数:

int roundedNumber = ExtensionMethods.RoundOff(236); // returns 240
int roundedNumber2 = ExtensionMethods.RoundOff(11); // returns 10

18
投票

使用Math.Ceiling始终向上舍入。

int number = 236;
number = (int)(Math.Ceiling(number / 10.0d) * 10);

模数(%)获得余数,因此得到:

// number = 236 + 10 - 6

把它放到扩展方法中

public static int roundupbyten(this int i){
    // return i + (10 - i % 10); <-- logic error. Oops!
    return (int)(Math.Ceiling(i / 10.0d)*10); // fixed
}

// call like so:
int number = 236.roundupbyten();

以上编辑:我应该用我的第一直觉去使用Math.Ceiling

blogged about this when calculating UPC check digits


7
投票

这可能有点太晚了但我想有一天这可能会有很好的帮助......

我试过这个:

public int RoundOff(int number, int interval){
    int remainder = number % interval;
    number += (remainder < interval / 2) ? -remainder : (interval - remainder);
    return number;
}

使用:

int number = 11;
int roundednumber = RoundOff(number, 10);

这样,您可以选择是否将间隔的一半向上舍入或向下舍入。 =)


3
投票

将float舍入为整数类似于(int)(x + 0.5),而不是简单地转换x - 如果你想要10的倍数,你可以很容易地调整它。

如果您只想进行整数数学运算并将其四舍五入,请尝试(x + 10/2)/ 10 * 10。

编辑:我注意到这个回复不符合原作者的请求,也是一种偏向的舍入形式,我不想这样做。然而,另一个已接受的响应已经说明了Math.round(),这是一个更好的解决方案。


1
投票

老问题,但这里是一种方法来做已经被问过的问题加上我扩展它以能够将任何数字四舍五入到你想要的sig figs数量。

    private double Rounding(double d, int digits)
    {
        int neg = 1;
        if (d < 0)
        {
            d = d * (-1);
            neg = -1;
        }

        int n = 0;
        if (d > 1)
        {
            while (d > 1)
            {
                d = d / 10;
                n++;
            }
            d = Math.Round(d * Math.Pow(10, digits));
            d = d * Math.Pow(10, n - digits);
        }
        else
        {
            while (d < 0.1)
            {
                d = d * 10;
                n++;
            }
            d = Math.Round(d * Math.Pow(10, digits));
            d = d / Math.Pow(10, n + digits);
        }

        return d*neg;
    }


   private void testing()
   {
       double a = Rounding(1230435.34553,3);
       double b = Rounding(0.004567023523,4);
       double c = Rounding(-89032.5325,2);
       double d = Rounding(-0.123409,4);
       double e = Rounding(0.503522,1);
       Console.Write(a.ToString() + "\n" + b.ToString() + "\n" + 
           c.ToString() + "\n" + d.ToString() + "\n" + e.ToString() + "\n");
   }

1
投票

我更喜欢不引入Math库,也不去浮点,所以我的建议只是做下面的整数运算,我将向下舍入到下一个1K。如果您不想重复,请将其包装在方法或lambda片段中。

int MyRoundedUp1024Int = ((lSomeInteger + 1023) / 1024) * 1024;

我还没有对其他方式进行性能测试,但我敢打赌,这是最快的方法,可以省去这个版本的移位和旋转。

© www.soinside.com 2019 - 2024. All rights reserved.