首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 階乘求和:1! + 2! + 3! + ... + 20! (含長整型溢出分析)

     編輯:Java 相關知識

問題與風險

原代碼計算前 10 項 (而非 20),且用 long 類型。階乘增長極快:

前 20 項和 2561327494111820313 仍在 long 範圍內,但 21! 會溢出。

修正版:計算前 20 項

public class FactorialSum {
    public static void main(String[] args) {
        long sum = 0;
        long fact = 1;
        
        for (int i = 1; i <= 20; i++) {
            fact *= i;      // 計算 i!
            sum += fact;    // 累加
            System.out.printf("%2d! = %,25d  累加和 = %,25d%n", i, fact, sum);
        }
        
        System.out.println("\n前 20 項階乘和 = " + sum);
        // 2561327494111820313
    }
}

BigInteger 無限精度版本 (推薦)

import java.math.BigInteger;

public class FactorialSumBigInt {
    public static void main(String[] args) {
        BigInteger sum = BigInteger.ZERO;
        BigInteger fact = BigInteger.ONE;
        
        for (int i = 1; i <= 30; i++) {  // 可算任意大
            fact = fact.multiply(BigInteger.valueOf(i));
            sum = sum.add(fact);
            System.out.printf("%2d! = %s%n", i, fact);
        }
        
        System.out.println("\n前 30 項和 = " + sum);
    }
}

遞歸版本 (教學用,非生產)

public class FactorialRecursive {
    // 尾遞歸風格 (Java 不優化尾調用)
    static long fact(long n) {
        return n <= 1 ? 1 : n * fact(n - 1);
    }
    
    public static void main(String[] args) {
        long sum = 0;
        for (int i = 1; i <= 20; i++) {
            sum += fact(i);
        }
        System.out.println(sum);
    }
}

性能對比

nn!是否溢出 long (9.22×10¹⁸)
103,628,800✅ 安全
151.3×10¹²✅ 安全
202.43×10¹⁸⚠️ 接近上限
215.1×10¹⁹💥 溢出

總結

階乘求和是「累乘 + 累加」雙重累積模式。關鍵風險是整數溢出:int 13! 即溢出,long 21! 溢出。實際開發:默認用 BigInteger,除非確定範圍極小且性能極度敏感。遞歸版僅適合教學,生產環境嚴禁遞歸計算階乘 (棧溢出、重複計算、無尾調用優化)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
方法時間複雜度空間複雜度適用場景
迭代累乘O(n)O(1)生產首選
遞歸O(n)O(n) 棧教學演示
BigIntegerO(n × M(log n))O(log n)大數/任意精度
查表 (預計算)O(1)O(n) 存儲高頻調用固定範圍