大家好,我正在研究如何计算2的下一个幂,偶然发现了如下代码:

int x;//assume that x is already initialized with a value
--x;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
return x+1;


当我使用正数运行时,它工作正常,但不适用于我不了解的负数,因为我认为就为它寻找下一个二的幂而言,数字是正数还是负数都没有关系。如果我们有数字5,我们想找到2的下一个幂。如果我们直观地考虑,我们知道它的8,因为8大于5,而8等于2 ^ 3。如果我尝试使用负数,我总是会一直得到0,但我不明白,因为0不是2的幂

最佳答案

简短的答案是因为C ++标准指出>>运算符对负值产生的值是实现定义的,而对于正值,其结果是除以2的幂。

过于简单地说,术语“定义的实现”表示该标准允许结果在不同实现之间(即在编译器之间)变化。除其他事项外,这意味着无法保证它将以与正值相同的方式工作(明确规定了其行为)。

原因是signed int的表示形式也是实现定义的。例如,这允许使用二进制补码表示法-尽管实际上有时会使用(尽管有时会使用其他表示法)。

在数学上,二进制补码的右移等效于除以2的幂,并且向下舍入到-infinity(而不是零)。对于正值,朝零取整和向-infinity取整具有相同的效果(零和-infinity均小于任何正整数值)。对于负值,它们则不这样(四舍五入是从零开始,而不是接近零)。

10-08 13:20