为了账号安全,请及时绑定邮箱和手机立即绑定

左移位负移位计数

左移位负移位计数

C
蛊毒传说 2019-09-03 15:29:24
这到底发生了什么?a << -5显然它没有正确转变。但我正在阅读的这本书指出:在一台机器上,这个表达式实际上是左移27位我的问题是; 为什么?什么原因导致27位左移?在使用负移位计数换档时会发生什么?谢谢。
查看完整描述

3 回答

?
守候你守候我

TA贡献1802条经验 获得超10个赞

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

ISO 9899:2011 6.5.7逐位移位运算符:

对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为未定义


查看完整回答
反对 回复 2019-09-03
?
江户川乱折腾

TA贡献1851条经验 获得超5个赞

正如其他成员已经回答的那样,它会产生未定义的行为。我想在这里提一下,你引用这本书(“在一台机器上”)似乎是偏袒的。它没有概括行为。该书也可能已经解释了该行为未按照标准定义。顺便说一句,我刚刚通过“新C标准 - 经济和文化评论”并发现了这一说法:

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

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


查看完整回答
反对 回复 2019-09-03
?
LEATH

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的产品相同。


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


查看完整回答
反对 回复 2019-09-03
  • 3 回答
  • 0 关注
  • 511 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信