3 回答
TA贡献1802条经验 获得超10个赞
右侧的负整数是C语言中未定义的行为。
ISO 9899:2011 6.5.7逐位移位运算符:
对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为未定义。
TA贡献1851条经验 获得超5个赞
正如其他成员已经回答的那样,它会产生未定义的行为。我想在这里提一下,你引用这本书(“在一台机器上”)似乎是偏袒的。它没有概括行为。该书也可能已经解释了该行为未按照标准定义。顺便说一句,我刚刚通过“新C标准 - 经济和文化评论”并发现了这一说法:
英特尔奔腾SAL指令(由gcc和Microsoft C ++生成以评估左移)仅使用移位量的后五位
这很好地解释了为什么-5的左移可能导致左移27(对于负数的2的补码表示)
TA贡献1936条经验 获得超6个赞
int main()
{
unsigned int a = 1;
printf("%u\n",a<<(-1));
return 0;
}
输出为2147483648。
这是我的假设和验证:(只是假设!)
1.“<<”右操作数必须是unsigned int类型,
首先,(int)“-1”将被转换为(unsigned int)“ - 1”。原因int类型是二进制补码表示,结果将是2 ^ 32-1(unsigned int)
2.由于数字2 ^ 32-1大于最大位移数字,2 ^ 32 - 1将是mod 32,等于27
我还尝试了一些其他的nagetive右操作数,并且带有假定规则的手动计算结果与我的IDE的产品相同。
我试图找到一些支持的官方文件,女巫可以证实我的假设是否正确。也许你可以告诉我。
- 3 回答
- 0 关注
- 511 浏览
添加回答
举报