我必须在这里绝对疯了,但是我机器上的gcc 4.7.3
给出了最荒谬的结果。这是我正在测试的确切代码:
#include <iostream>
using namespace std;
int main(){
unsigned int b = 100000;
cout << (b>>b) << endl;
b = b >> b;
cout << b << endl;
b >>= b;
cout << b << endl;
return 0;
}
现在,任何自行右移的数字都将导致 0 (带有整数除法的
n/(2^n) == 0
,n>1
和正/无符号),但是这是我的输出:100000
100000
100000
我疯了吗?可能会发生什么?
最佳答案
在C++和C中一样,移位仅限于移位值的大小(以位为单位)。例如,如果unsigned int是32位,则未定义大于31的移位。
在实践中,常见的结果是使用了移位量的5个最低有效位,而忽略了高位。这是由于编译器生成的机器指令可以做到这一点(例如x86上的SHR)。
在这种情况下,移位值为100000
(十进制),碰巧是二进制的11000011010100000
-低5位为零。因此,您实际上得到了0的偏移。但是,您不应该依赖于此。从技术上讲,您所看到的是不确定的行为。
引用文献:
对于C,N1570第6.5.7节:
对于C++,N3690第5.8节“[expr.shift]”:
N1570是草稿,几乎与已发布的ISO C11标准相同;自1989年ANSI C标准以来,该条款几乎相同。
N3690是C++标准的最新草案;我不确定这是否是最好的使用方式,但是再次,此子句没有改变。
关于c++ - 算术右移给出假结果吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19636539/