C:四舍五入到最接近的倍数

Jef*_*f L 6 c rounding

这感觉像是一个基本问题,但到目前为止我找不到明确的答案。

我想实现一个高效的函数round_to_nearest(int x, int multiple),将有符号整数四舍五入x到最接近的倍数multiple,尽可能避免使用浮点算法。

示例输出:

round_to_nearest(14, 5);
15

round_to_nearest(16, 5);
15

round_to_nearest(23, 5);
25

round_to_nearest(22, 5);
20

round_to_nearest(-23, 5);
-25

round_to_nearest(-22, 5);
-20
Run Code Online (Sandbox Code Playgroud)

Cli*_*ord 4

在整数算术中,如果 n为正数,则添加m/2,否则减去m/2,然后除以m(截断整数除法),然后乘以m

int round_to_nearest( int n, int m )
{
    return (( n + ((n < 0) ? -m : m) / 2) / m ) * m ;
}
Run Code Online (Sandbox Code Playgroud)
int main()
{
    int test[] = {16, 23, 22, -23, -22} ;
    int m = 5 ;
    
    for( int i = 0; i < sizeof(test) / sizeof(*test); i++ )
    {
        printf(" round_to_nearest( %d, %d ) = %d\n", test[i], m, 
                                                     round_to_nearest( test[i], m ) ) ;
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

测试输出:

int round_to_nearest( int n, int m )
{
    return (( n + ((n < 0) ? -m : m) / 2) / m ) * m ;
}
Run Code Online (Sandbox Code Playgroud)

需要注意的是m必须 > 0 - 在这种情况下这是有道理的,我会接受它作为正确操作的先决条件;将其作为运行时错误进行检查可能是不必要的,但您可以包含一个断言来防止程序员语义错误:

assert( m > 0 ) ;
Run Code Online (Sandbox Code Playgroud)

标准库断言在定义时被删除NDEBUG- 通常是在禁用调试支持时。