数学舍入法

Math rounding method

我正在尝试找到一些用于此类舍入的 Math,如果它作为方法存在:

3219 to 3300
11380 to 11400
12583 to 12600
8275 to 8300
1778 to 1800
399 to 400
340 to 400
305 to 400
266 to 300
123 to 200
32 to 100
3 to 100
1 to 100

根据您的示例,您想四舍五入到最接近的 100,您可以这样做:

int x = 3219; // or any other input
int result = (x+99)/100*100;

这个算法的优点是你留在整数世界。所以这意味着没有舍入错误(只要子结果可以表示为整数),我们就可以了。

您可以概括此方法,例如:

public static int RoundUp(this int x, int n = 100) {
    return (x+n-1)/n*n;
}

其中 n 是您要向上舍入的数字。

根据@wenston的回答,你可以构造一个branchfree算法,它不受整数溢出的影响:

public static int RoundUp(this int x, int n = 100) {
    int r = x % n;
    return x + (n - r) % n;
}

使用这个:

var value = 1234;
var result = (int)(Math.Ceiling(value/100f)*100);

为了防止中间结果出现整数溢出问题(例如RoundUp(2147482999, 1000)),我们不应该在除法之前将n添加到x

public static int RoundUp(int x, int n) {
    var r = x % n;
    if (r == 0) return x;
    return x + n - r;
}

x % n 是除法的余数。如果这是非零的,我们需要添加在 [1..n] 范围内的这个 (n - x % n) 的补语。当它是 == n 时,我们实际上希望它加零,所以我们可以通过另一个 % n 实现这一点,如 ,这使得它没有分支但有两个 mods 而不是一个。

public static int RoundUp(int x, int n) {
    return x + (n - x % n) % n;
}

而且,提醒一下,如果你真的关心除此之外的整数溢出,那么你可以包装在一个 checked 块中:

public static int RoundUp(int x, int n) {
    checked
    {
        return x + (n - x % n) % n;
    }
}