我必须在这里绝对疯了,但是我机器上的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) == 0n>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/

10-08 22:07
查看更多