java移位运算符不溢出而是按位宽取模截断高位:int右操作数对32取模,long对64取模;有符号右移>>负数补1,无符号右移>>>负数变大正数;边界值如32、64易致逻辑错误。

Java移位运算符不会“溢出”,但会静默丢弃高位
Java中、<code>>>、>>>对int或long操作时,**不抛异常、不报错、不截断值域**,而是按位宽取模后直接截断高位——这不是溢出,是定义行为。比如int是32位,1 等价于<code>1 即<code>1 ,结果是8。
-
int移位时,右操作数自动对32取模(value % 32),long则对64取模 - 负数左移(如
-1 )结果仍是补码表示的负数,不是“变正”或“溢出报错” - 写
i 对<code>int来说等于i ,也就是原值——这点常被忽略,导致循环移位逻辑出错
有符号右移>>在负数上会补1,不是简单除2
对负数用>>,高位补的是符号位(1),不是0。所以-8 >> 1是-4,没错;但-1 >> 1是-1(0xFFFFFFFF >> 1 → 0xFFFFFFFF),不是0。它模拟的是“向下取整的算术右移”,不是数学除法。
-
-1 >> n对任意n > 0都还是-1,因为全1补1后仍是全1 - 想实现“向零取整”的右移(如
-5 / 2 == -2),不能直接用>>,得先转正再移再加符号 -
>>和/对正数等价,对负数不等价:比如-5 >> 1 == -3,而-5 / 2 == -2
无符号右移>>>对负数会变成很大正数
>>>不管符号位,一律补0。所以int型负数经>>>后,高位补0,低32位不变,结果是一个很大的正数。例如-1 >>> 1是0x7FFFFFFF即2147483647。
Java开发手册规约集合,基于阿里巴巴Java开发手册(嵩山版)。 涵盖7大维度:编程规约、异常日志、单元测试、安全规约、MySQL数据库、工程结构、设计规约。 当用户需要:(1) 编写或审查Java代码 (2) 检查命名/代码规范 (3) 处理异常和日志 (4) 编写单元测试 (5) 安全编码 (6) 数据库设...
-
>>>只对int和long有意义;byte/short会先提升为int再运算,注意隐式类型提升陷阱 - 用
>>>提取高位字节时(如(i >>> 24) & 0xFF),必须确保操作的是int或long,否则提升后可能多出无效位 -
>>>不能用于“安全除2”,因为-1 >>> 1不是0.5取整,而是彻底改变了数值语义
边界测试要覆盖0、31/32、63/64这些关键位数
移位右操作数为0、32(int)、64(long)时行为特殊:它们触发取模归零,容易写出“以为移了但其实没动”的bug。测试时别只试1、2、16。
- 对
int,测试i 、<code>i 、<code>i 、<code>i ——后两者分别等价于<code>i 和<code>i - 对负
int,测-1 >> 31(结果-1)、-1 >>> 31(结果1)、-1 >>> 32(等价于>>> 0,还是-1) - 用
Integer.MIN_VALUE 验证是否得到0(是的,因为符号位被移出,高位补0,结果是<code>0x80000000 )
真正容易翻车的,不是大数字,而是那些刚好卡在32/64倍数上的移位数——它们让代码看起来“运行正常”,实则逻辑已偏移。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










