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

Java组合数计算程序大数值输入输出0异常求助

问题原因分析

你的程序输出0的核心问题是long类型的整数溢出。

Java中long的最大值是9223372036854775807,而50的阶乘(50!)约等于3.04140932×10^64,这个数值远远超出了long的存储范围。当计算nFactorial时,乘到某个数后就会溢出,溢出后的数值会变成负数或者0(取决于溢出的次数),最终导致nFactorial / (rFactorial * minusFactorial)的结果为0。

解决方案

这里提供两种可行的修复方式:

方式一:使用BigInteger处理大数值

BigInteger可以支持任意大小的整数运算,完全避免溢出问题,修改后的代码如下:

import java.math.BigInteger;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter element number: ");
        int n = scanner.nextInt();
        System.out.print("selection number: ");
        int r = scanner.nextInt();
        int minus = n - r;

        BigInteger nFactorial = BigInteger.ONE;
        BigInteger rFactorial = BigInteger.ONE;
        BigInteger minusFactorial = BigInteger.ONE;

        for(int i = 1; i <= n; i++) {
            nFactorial = nFactorial.multiply(BigInteger.valueOf(i));
        }
        for(int i = 1; i <= r; i++) {
            rFactorial = rFactorial.multiply(BigInteger.valueOf(i));
        }
        for(int i = 1; i <= minus; i++) {
            minusFactorial = minusFactorial.multiply(BigInteger.valueOf(i));
        }

        BigInteger comb = nFactorial.divide(rFactorial.multiply(minusFactorial));
        System.out.println("C(" + n + "," + r + ") combination: " + comb);
    }
}

方式二:优化计算逻辑,分步约分

直接计算大阶乘效率低且容易溢出,我们可以利用组合数的公式特性,分步计算并约分,减少中间结果的大小:
组合数公式可转化为:
C(n,r) = n*(n-1)*...*(n-r+1)/(r*(r-1)*...*1)
这样只需要计算r次乘法和除法,中间结果不会过大,修改后的代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter element number: ");
        int n = scanner.nextInt();
        System.out.print("selection number: ");
        int r = scanner.nextInt();
        
        // 取r和n-r中的较小值,减少计算次数
        r = Math.min(r, n - r);
        long result = 1;
        
        for (int i = 1; i <= r; i++) {
            // 先乘再除,保证每次除法都是整数
            result = result * (n - r + i) / i;
        }
        
        System.out.println("C(" + n + "," + r + ") combination: " + result);
    }
}

这种方式不仅避免了溢出,还提升了计算效率,对于C(50,5)的计算,中间结果始终在long的范围内,能得到正确结果2118760。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 01:01:20