java中long乘法溢出需预判:b>0时a≤long.max_value/b且a≥long.min_value/b;b

Java中long类型取值范围是-2⁶³到2⁶³−1(即-9223372036854775808L ~ 9223372036854775807L)。直接相乘可能溢出,但Java不会抛异常,而是静默回绕。要安全检测,不能依赖结果再判断,而应在运算前做数学预判。
利用数学边界提前判断是否溢出
两个long数a和b相乘,若不溢出,则必须满足:
当b > 0时:a ≤ Long.MAX_VALUE / b 且 a ≥ Long.MIN_VALUE / b
当b
当b == 0时,结果恒为0,不会溢出
- 关键点:用整数除法做阈值比较,避免实际乘法发生
- 注意Long.MIN_VALUE / b在b = -1时会溢出(因为|Long.MIN_VALUE|比Long.MAX_VALUE大1),需单独处理
- 推荐用Math.multiplyExact(long, long)(Java 8+),它内部已实现该逻辑并抛ArithmeticException
手写安全乘法方法(兼容老版本JDK)
以下是一个可直接使用的静态工具方法:
public static long safeMultiply(long a, long b) {
if (b == 0) return 0;
if (a > 0 && b > 0 && a > Long.MAX_VALUE / b) throw new ArithmeticException("long overflow");
if (a 0 && b 0 && a <p>说明:<br>
• 四种符号组合分别判断,覆盖所有溢出场景<br>
• 使用整数除法(截断向零)是安全的,因我们只关心是否“越过边界”<br>
• 不用浮点运算,避免精度丢失和性能开销</p><h3>使用Math.multiplyExact简化开发</h3><p>Java 8起提供标准API,语义清晰、经过充分测试:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill7957" title="js2java"><img
src="https://img.php.cn/upload/skill/000/000/081/179178140274370.jpg" alt="js2java" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill7957" title="js2java" class="overflowclass">js2java</a>
<p class="overflowclass">JavaScript 到 Java 全栈翻译助手,专为前端开发者学习 Java 或快速实现后端业务逻辑而设计。当用户提到以下场景时必须使用此技能: - "帮我把这段 JS 代码转成 Java" - "用 Java 怎么写这个逻辑" - "我习惯用 JS 写,想翻译成 Java" - "教我 Java,我要写后端接...</p>
</div>
<a rel="nofollow" href="/xiazai/skill7957" title="js2java" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div><pre class="brush:java;toolbar:false;">try {
long result = Math.multiplyExact(a, b);
// 正常使用result
} catch (ArithmeticException e) {
// 处理溢出,例如降级为BigInteger或抛业务异常
}
- 底层逻辑与手写方法一致,但更可靠
- 适合多数业务场景,无需重复造轮子
- 若需自定义溢出行为(如返回null、默认值或日志记录),再封装一层即可
扩展:支持返回Optional或布尔标记
有些场景不希望抛异常,可用返回值方式:
public static Optional<long> tryMultiply(long a, long b) {
try {
return Optional.of(Math.multiplyExact(a, b));
} catch (ArithmeticException e) {
return Optional.empty();
}
}</long>
或更轻量的布尔检查方法:
public static boolean willOverflow(long a, long b) {
try {
Math.multiplyExact(a, b);
return false;
} catch (ArithmeticException e) {
return true;
}
}
按需选择——异常适合错误场景,Optional适合函数式链式调用,布尔值适合快速校验。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










