这感觉像是一个基本问题,但到目前为止我找不到明确的答案。
我想实现一个高效的函数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)
在整数算术中,如果 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
- 通常是在禁用调试支持时。