算术右移给出假结果? [英] Arithmetic right shift gives bogus result?

查看:133
本文介绍了算术右移给出假结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须在这里绝对疯狂,但在我的机器上的 gcc 4.7.3 是最荒谬的结果。这里是我测试的确切代码:

I must be absolutely crazy here, but gcc 4.7.3 on my machine is giving the most absurd result. Here is the exact code that I'm testing:

#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> 1 ( n /(2 ^ n)== 0 code>和 positive / unsigned ),但不知何故这里是我的输出:

Now, any number that's right shifted by itself should result in 0 (n/(2^n) == 0 with integer divide, n>1, and positive/unsigned), but somehow here is my output:

100000
100000
100000

我疯了吗?

推荐答案

在C ++中,与C中一样,移位被限制为值偏移。例如,如果unsigned int是32位,则大于31的移位未定义。

In C++ as in C, shifts are limited to the size (in bits) of the value shifted. For instance, if unsigned int is 32 bits, then a shift of more than 31 is undefined.

在实践中,这意味着如果编译器在编译时可以确定移位量太大,它可能选择不执行移位(实际上它可能产生的代码,只是什么,但这是一个常见的实际结果)。另一个常见的结果是使用移位量的5个最低有效位,并且忽略高阶位;这是因为编译器生成一个机器指令(例如x86上的SHR)。

In practice, this means that if the compiler can determine at compile time that the shift amount is too great, it may elect not to perform the shift at all (in fact it may produce code that does just about anything, but this is a common practical result). Another common result is that the 5 least-significant bits of the shift amount are used and the higher order bits are ignored; this is due to the compiler producing a machine instruction which does exactly that (eg SHR on x86).

参考文献:

对于C, N1570 部分6.5.7:

For C, N1570 section 6.5.7:


如果右操作数的值为负或大于或
等于提升的左操作数的宽度,是
未定义。

If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.

对于C ++, N3690 第5.8节[expr.shift]:

For C++, N3690 section 5.8 "[expr.shift]":


如果右操作数为负,或者大于或等于提升的左操作数的位长度的
,行为是未定义的。

The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.

N1570是一个草稿,几乎与发布的ISO C11标准相同;这个子句自1989年的ANSI C标准以来几乎是一样的。

N1570 is a draft, nearly identical to the released ISO C11 standard; this clause has been pretty much the same since the 1989 ANSI C standard.

N3690是最近的C ++标准草案;我不确定是否是最好的一个使用,但是,这个子句没有改变。

N3690 is a recent draft of the C++ standard; I'm not sure whether it's the best one to use, but again, this clause hasn't changed.

这篇关于算术右移给出假结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆