左移,负移位数

到底发生了什么?

a << -5

显然它不会右移。 但是我正在读的这本书说:

在一台机器上,这个expression式实际上做了27位的左移

我的问题是 为什么? 是什么导致了27位的左移? 当转移负移位数时究竟发生了什么? 谢谢。

右侧的负整数在C语言中是未定义的行为。

ISO 9899:1999 6.5.7按位移位运算符§3

整数升级在每个操作数上执行。 结果的types是升级的左操作数的types。 如果右操作数的值为负或大于或等于提升的左操作数的宽度, 则行为是不确定的

正如其他成员已经回答,它产生未定义的行为。 我想在这里提到的是,你从这本书(“在一台机器上”)引用似乎是部分的。 它没有概括的行为。 本书也可能已经解释说,行为是不符合标准的。 顺便说一句,我刚刚通过“新C标准 – 一个经济和文化评论”,并发现这一说法:

英特尔奔腾SAL指令(由gcc和Microsoft C ++生成以评估左移)仅使用移位量的最低五位

这很好地解释了为什么-5的左移可能导致左移27(对于负数的2的补码表示)

行为是不确定的。

在5位二进制算术中,2的补码-5与无符号+27具有相同的二进制表示,这可能解释了特定的平台。

如果你正在移动的值是一个32位的variables,那么移位-5进入一个“循环”并向前移动27。 换档只能以“未签名”的方式进行。

 int main() { unsigned int a = 1; printf("%u\n",a<<(-1)); return 0; } 

输出是2147483648。

这是我的假设和validation:(只是假设!)

1.“<<”右边的操作数必须是unsigned inttypes,

所以首先将(int)“-1”转换为(unsigned int)“-1”。 原因inttypes是二进制补码表示,结果将是2 ^ 32-1(unsigned int)

由于数字2 ^ 32-1大于最大位移数字,所以2 ^ 32-1将是模数32,其等于27

也尝试了一些其他的正确的操作数的数字,手工计算结果与假定的规则将与我的IDE的产品相同。

我想找一些支持官方文件,女巫可以validation我的假设是否正确。 也许你可以告诉我。