当前位置:首页 > 后端开发 > 正文

Java中两个long怎么相减?

在Java中,long类型相减直接使用减号(-)操作符即可, 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),其相减操作直接使用减法运算符 ,但需特别注意数值溢出问题,以下是详细说明:


基础相减操作

直接使用 运算符即可完成相减:

Java中两个long怎么相减?  第1张

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);
    }
}

最佳实践总结

  1. 常规计算:直接使用 a - b
  2. 安全关键场景:优先用 Math.subtractExact()
  3. 超范围计算:迁移到 BigInteger
  4. 测试:对边界值(如 Long.MIN_VALUELong.MAX_VALUE)进行单元测试。

引用说明

  • 基于 Oracle Java 官方文档:Primitive Data Types 和 Math.subtractExact() 规范。
  • 溢出检测逻辑参考《Effective Java》第3版(Joshua Bloch)第60条建议。
0