You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带符号long long大数右移操作异常原因咨询

带符号长整型移位操作的异常现象解析

当对字节执行移位操作时,存在一些不符合预期的场景。例如执行以下代码:

printf("shifted bytes %llx\n", (((long long)1 << 63 ))>>1);

其输出为c000000000000000,但使用unsigned long long类型或初始左移位数小于63时不会出现该问题。由于1在带符号与无符号long long中均存储为0000000000000001,且仅执行位运算,理论上不应存在差异,请问该现象为何会发生?


这是因为带符号整数的右移是算术右移,而无符号整数的右移是逻辑右移,二者行为完全不同,核心差异在于符号位的处理:

  • 第一步:(long long)1 << 63
    对于64位带符号long long,最高位是符号位(0表示正数,1表示负数)。将值为1(二进制仅最低位为1,其余全0)的带符号数左移63位后,符号位被置为1,得到long long类型的最小值:0x8000000000000000(二进制最高位为1,其余位全0)。
    注:虽然C标准对带符号数左移溢出的行为定义为未定义,但主流编译器都会按算术移位规则处理,直接移动位并保留符号位的变化。

  • 第二步:将上述结果右移1位
    带符号整数的算术右移会用符号位(此时为1)填充左侧空出的位,而非用0填充。因此0x8000000000000000右移1位后,最高两位变为11,其余位为0,最终结果就是0xc000000000000000,与你看到的输出一致。

  • 无符号类型无异常的原因
    使用unsigned long long时,右移是逻辑右移,无论何种情况都用0填充左侧空位。(unsigned long long)1 << 63得到0x8000000000000000,再右移1位会变成0x4000000000000000,符合"单纯移位"的预期结果。

  • 左移位数小于63时无异常的原因
    当左移位数小于63时,带符号数的符号位不会被置1,移位后仍为正数。此时算术右移和逻辑右移的效果一致(符号位为0,填充的也是0),所以结果与无符号类型的移位结果相同。

内容的提问来源于stack exchange,提问作者user20695956

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 19:32:15