内置.Net算法,可将值四舍五入到最接近的10个间隔


69

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

我可以轻松地手工完成

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

但是我正在寻找一种内置算法来完成这项工作,例如Math.Round()。我不愿意手工做的原因是,我不想为我的整个项目编写相同或相似的代码,即使是像上面这样简单的事情也是如此。


6
如果可行,您为什么还需要其他东西?只需将其包装在扩展方法或公共库中并运行即可
John Sheehan

3
((数字+ 5)/ 10)* 10-寻找内置组件的充分理由。:-)
Adam Liss

2
我注意到这个问题令人困惑,您可能应该编辑标题或张贴内容以使其更清晰。特别是,您要始终舍入还是舍入到最接近的10?
雷蒙德·马丁诺

2
雷蒙德(Raymond),根据问题的实际内容而不是标题,很显然是四舍五入到最接近的10。但是我也注意到模棱两可,并同意应更改标题以适应需要。
克里斯·查拉巴鲁克

2
@Adam:在方法中包装简单明了的代码行有什么问题?对我来说看起来并不棘手或令人困惑。
Ed S.

Answers:


104

类库中没有内置函数可以执行此操作。最接近的是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

1
这段代码有很多问题,即它无法编译(缺少返回类型),并且无法四舍五入。在你的榜样,它会返回230和10
戴夫·范登Eynde

1
它仍然不会返回240,因为您正在舍入。
Dave Van den Eynde 09年

1
实际运行它。这是源代码(包括测试类),甚至是源代码的构建。它可以正常工作。labs.coldacid.net/code/number-rounding-extension-method
Chris Charabaruk'3

3
问题要求“四舍五入”,但是此答案四舍五入。如果输入11,则应该返回20,而不是10。这就是为什么需要的原因Math.Ceiling()
Dan Diplo

4
丹·迪普洛(Dan Diplo):接下来的一句话描述了四舍五入。阅读整个问题,而不仅仅是它的第一句话。
克里斯·查拉巴鲁克

23

使用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的本能

在计算UPC校验位时,写了关于此的博客


2
尝试使用240。然后您会得到什么?或者说11点
克里斯·查拉巴鲁克

12

这可能为时已晚,但我想有一天可能会有所帮助...

我已经试过了:

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);

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


5

将浮点数舍入为整数类似于(int)(x + 0.5),而不是简单地强制转换x-如果您想要10的倍数,则可以轻松地对其进行调整。

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

编辑:我注意到此回复不符合原始作者的要求,并且也是我不愿意做的有偏见的四舍五入形式。但是,另一个已接受的响应已经说明了Math.round(),这是一个更好的解决方案。


1
我不得不说,即使这是我过去经常使用的技巧,Math.Round看起来也更加干净。
Dave Van den Eynde 09年

2

旧问题,但这是一种解决所要求问题的方法,我将其扩展为可以将任意数字四舍五入为所需的无花果数量。

    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");
   }

2

我宁愿不带Math库也不要浮点数,所以我的建议是像下面这样整数运算,向上取整到下一个1K。如果不想重复,可以将其包装在方法或lambda片段中。

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

我还没有对此进行过性能测试,但是我敢打赌,这是节省时间的最快方法,也许这是移位和旋转的版本。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.