long result = a - b;
,需注意数值范围(-2^63 ~ 2^63-1),若结果超出范围会静默环绕(溢出),不会抛出异常。在Java中,long
类型表示64位有符号整数(取值范围为 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807),其相减操作直接使用减法运算符 ,但需特别注意数值溢出问题,以下是详细说明:
基础相减操作
直接使用 运算符即可完成相减:
long a = 20000L; long b = 5000L; long result = a - b; // 结果: 15000
关键注意事项:溢出(Overflow)
当相减结果超出 long
的范围时,会发生静默溢出(无异常提示),导致结果错误:
long min = Long.MIN_VALUE; // -9,223,372,036,854,775,808 long max = Long.MAX_VALUE; // 9,223,372,036,854,775,807 // 错误示例 1:最小值减正数 → 结果变为正数(溢出) long error1 = min - 1; // 结果: 9,223,372,036,854,775,807(错误) // 错误示例 2:最大值减负数 → 结果变为负数(溢出) long error2 = max - (-1); // 结果: -9,223,372,036,854,775,808(错误)
解决方案:避免溢出
使用 Math.subtractExact()
(推荐)
Java 8+ 提供该方法,溢出时抛出 ArithmeticException
:
try { long safeResult = Math.subtractExact(min, 1); // 抛出异常 } catch (ArithmeticException e) { System.out.println("溢出发生!"); }
手动检查边界
通过逻辑判断预防溢出:
long subtract(long a, long b) { if (b > 0 && a < Long.MIN_VALUE + b) { throw new ArithmeticException("下溢"); } if (b < 0 && a > Long.MAX_VALUE + b) { throw new ArithmeticException("上溢"); } return a - b; }
使用 BigInteger
(超大数场景)
超出 long
范围时,转为 BigInteger
处理:
import java.math.BigInteger; BigInteger bigA = BigInteger.valueOf(min); BigInteger bigB = BigInteger.valueOf(1); BigInteger result = bigA.subtract(bigB); // 正确结果: -9,223,372,036,854,775,809
完整示例代码
public class LongSubtractionDemo { public static void main(String[] args) { // 基础相减 long normalResult = 100000L - 30000L; // 70,000 // 溢出处理 try { long safeDiff = Math.subtractExact(Long.MIN_VALUE, 1); } catch (ArithmeticException e) { System.out.println("捕获溢出: " + e.getMessage()); } // BigInteger 处理 BigInteger bigResult = BigInteger.valueOf(Long.MIN_VALUE) .subtract(BigInteger.ONE); System.out.println("BigInteger 结果: " + bigResult); } }
最佳实践总结
- 常规计算:直接使用
a - b
。 - 安全关键场景:优先用
Math.subtractExact()
。 - 超范围计算:迁移到
BigInteger
。 - 测试:对边界值(如
Long.MIN_VALUE
和Long.MAX_VALUE
)进行单元测试。
引用说明:
- 基于 Oracle Java 官方文档:Primitive Data Types 和 Math.subtractExact() 规范。
- 溢出检测逻辑参考《Effective Java》第3版(Joshua Bloch)第60条建议。
原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/26689.html