You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何识别long类型溢出错误?代码未抛出RuntimeException

问题分析与修复方案

核心问题1:缓存的负数结果直接返回,未触发异常

你的binomialCoefficient方法中,当缓存值不为0时直接返回,没有检查该值是否为负数(溢出结果)。如果某次计算溢出后将负数存入缓存,后续调用会直接返回这个负数,不会抛出异常。

核心问题2:main方法中变量未正确初始化

如果第一个try块捕获到输入异常(比如非数字输入),n、k、cache会处于未初始化/null状态,后续调用binomialCoefficient会引发额外异常,干扰溢出异常的处理。

修复后的代码

import java.util.Scanner;

public class combinations {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNextLine()){
            String[] input = sc.nextLine().split(" ");
            if(input.length==2){
                long n = 0;
                long k = 0;
                long[][] cache = null;
                try {
                    n = Long.parseLong(input[0]);
                    k = Long.parseLong(input[1]);
                    // 优化组合数计算:C(n,k)=C(n,n-k),减少递归次数
                    k = Math.min(k, n - k);
                    cache = new long[(int)(n + 1)][(int)(k + 1)];
                } catch (Exception e) {
                    System.out.println("输入无效,请输入两个合法的整数");
                    continue;
                }  

                try{
                    System.out.println(binomialCoefficient(n, k, cache));
                } catch (RuntimeException e) {
                    System.out.println(e.getMessage());
                }
            } else {
                System.out.println("输入格式错误,请输入两个空格分隔的整数");
            }
        }
        sc.close();
    }

    public static long binomialCoefficient(long n, long k, long[][] cache) {  
        if (k == 0 || k == n) {
            return cache[(int)n][(int)k] = 1;
        }
        // 检查缓存值,若为负数说明之前已溢出,直接抛异常
        if (cache[(int)n][(int)k] != 0) {
            if (cache[(int)n][(int)k] < 0) {
                throw new RuntimeException("Overflow occured");
            }
            return cache[(int)n][(int)k];
        }
        long left = binomialCoefficient(n-1, k-1, cache);
        long right = binomialCoefficient(n-1, k, cache);
        // 加法前检查是否会溢出,比溢出后检查更严谨
        if (left > Long.MAX_VALUE - right) {
            cache[(int)n][(int)k] = -1; // 标记溢出
            throw new RuntimeException("Overflow occured");
        }
        cache[(int)n][(int)k] = left + right;
        return cache[(int)n][(int)k];
    }
}

关键修复点

  • 缓存检查增强:返回缓存值前先判断是否为负数,若为负数直接抛出溢出异常。
  • 加法前溢出检查:在计算left + right前,判断left是否大于Long.MAX_VALUE - right,提前发现溢出,避免产生负数结果后再处理。
  • 组合数优化:利用C(n,k)=C(n,n-k)减少递归深度和计算量,同时缩小缓存数组的大小(只需到k即可,无需到n)。
  • 输入异常处理优化:输入无效时直接提示并跳过后续计算,避免未初始化变量引发的问题。

内容的提问来源于stack exchange,提问作者a2s4342

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 00:15:05