为何对小于256的数执行24位移位会得到负值?附代码示例
为什么对小于256的数执行24位移位操作会得到负值?
嘿,这个问题问到点子上了!咱们得从JavaScript位运算的底层逻辑说起,其实两个疑问本质是同一个原因——JS里的所有位运算都是基于32位有符号整数(补码形式)处理的,这就是关键所在。
先拆解你的代码例子,一步步看:
先看第一个表达式:(200<<23)>>23
200的二进制是11001000(只有8位)。左移23位后,这个8位会被移动到32位整数的第23位到第30位(从0开始计数),此时32位整数的最高位(第31位,符号位)还是0,所以这是一个正数。
接着执行算术右移23位,因为是正数,右移时会在高位补0,相当于把原来的8位移回低位,最终结果就是200,自然是正值。
再看第二个表达式:(200<<24)>>24
这时候重点来了:200左移24位后,原来的8位11001000会被直接移到32位整数的最高8位——也就是第24位到第31位。而第31位恰好是32位有符号整数的符号位,200的二进制最高位是1,所以这时候符号位被设为1,整个数就变成了一个负数的补码形式。
接下来执行算术右移24位,这时候因为符号位是1,JS会在高位补1(而不是0),最终得到的结果就是把原来的8位11001000当成8位有符号数的十进制值——也就是-56(因为8位有符号数里11001000的补码对应的原数是-56)。
核心总结
- JS的位运算会强制把操作数转换成32位有符号整数,超出这个范围的位会被直接丢弃
- 左移操作可能会把原数的高位(1)推到符号位,导致数变成负数
- 算术右移(
>>)会根据符号位填充高位:正数补0,负数补1,所以负数右移后依然保持负数属性
验证一下代码:
console.log( (200<<23)>>23 ); // 输出 200 console.log( (200<<24)>>24 ); // 输出 -56
内容的提问来源于stack exchange,提问作者Kamil Kiełczewski
相关产品推荐
相关产品推荐

