左移,负移位数
到底发生了什么?
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我的假设是否正确。 也许你可以告诉我。