这是从Linux内核3.12.1获取的二进制搜索算法。由于size_t
总是>=0
,我想知道为什么我们不将/2
替换为>>
?
/**
* @key: pointer to item being searched for
* @base: pointer to first element to search
* @num: number of elements
* @size: size of each element
* @cmp: pointer to comparison function
*/
void *bsearch(const void *key, const void *base, size_t num, size_t size,
int (*cmp)(const void *key, const void *elt))
{
size_t start = 0, end = num;
int result;
while (start < end)
{
size_t mid = start + (end - start) / 2;
result = cmp(key, base + mid * size);
if (result < 0)
end = mid;
else if (result > 0)
start = mid + 1;
else
return (void *) base + mid * size;
}
return NULL;
}
答案 0 :(得分:3)
因为那是过早的优化 - 而且很可能编译器足够聪明地实现并且会将除法改为两个右移。
答案 1 :(得分:1)
您只需要提供它没有的编译器信息。编译器已经知道size_t
是无符号类型,因此它可以编译/ 2
,就像它已经是>> 1
一样。任何现代编译器都会进行这种转换。
有时,程序员拥有编译器没有的信息。它可以是这样的:
/* requires y to be larger than x */
int f(int x, int y) {
int z = y - x;
return z / 2;
}
在上面的函数中,编译器不能将除法转换为简单的移位(尽管它可以将其转换为使用移位的较长序列并避免除法)。在这种情况下,您可以考虑撰写>> 1
而不是/ 2
。但是,当从程序中简单地推断出信息时,让编译器推断它。如果您注意到,在阅读生成的程序集时(您应该这样做:它可以让您省去问这个问题的麻烦),考虑到易于获得的信息生成次优代码,提交改进请求编译器的开发人员,而不是使源代码的可读性降低。