int r2 (int a, int b)
{
return (a + (1<<(b-1))) >>b;
}
int r3 (int a, int b)
{
return (a + (1<<(b-1)) -1 -(a>>31)) >>b;
}
- 它们之间有什么区别?
- 像r3()函数中使用额外的操作有什么优势?
这个问题在面试中问到了我,我很容易地能够扩展表达式,但是对于第二个问题我没有得到答案。
int r2 (int a, int b)
{
return (a + (1<<(b-1))) >>b;
}
int r3 (int a, int b)
{
return (a + (1<<(b-1)) -1 -(a>>31)) >>b;
}
这个问题在面试中问到了我,我很容易地能够扩展表达式,但是对于第二个问题我没有得到答案。
1. 它们之间有什么区别?
两者都执行2的幂次方除法并将结果四舍五入到最近的整数(如果b
在一个小范围之外则会有UB)。r2
向上舍入。 r3
向0舍入。
2. 在函数r3()中使用额外操作的优点是什么?
r3
执行类似于int
除法的舍入。 int
除法向0截断。
注意:随着64位int
的出现以及使用16位int
的嵌入式处理器的兴起,硬编码的31
是值得质疑的编码方式。应该使用像a>>(sizeof(int) * CHAR_BIT - 1)
这样的代码来代替a>>31
。
对我来说,这是第一件引人注目的事情。这为可能了解公司市场的人提供了一个展示如何狭隘地看待C语言可能会对公司产生不利影响的机会。
不要只考虑回答问题,还要考虑问题的适用性。
a
,而第一个只适用于正数a
。 - dreamlax-1 -(a>>31)
... 我能获得奖励吗? :) - Paul Evans