| n | n! | 是否溢出 long (9.22×10¹⁸) |
| 10 | 3,628,800 | ✅ 安全 |
| 15 | 1.3×10¹² | ✅ 安全 |
| 20 | 2.43×10¹⁸ | ⚠️ 接近上限 |
| 21 | 5.1×10¹⁹ | 💥 溢出 |
前 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);
}
}
性能對比
| 方法 | 時間複雜度 | 空間複雜度 | 適用場景 |
| 迭代累乘 | O(n) | O(1) | 生產首選 |
| 遞歸 | O(n) | O(n) 棧 | 教學演示 |
| BigInteger | O(n × M(log n)) | O(log n) | 大數/任意精度 |
| 查表 (預計算) | O(1) | O(n) 存儲 | 高頻調用固定範圍 |
總結
階乘求和是「累乘 + 累加」雙重累積模式。關鍵風險是整數溢出:int 13! 即溢出,long 21! 溢出。實際開發:默認用 BigInteger,除非確定範圍極小且性能極度敏感。遞歸版僅適合教學,生產環境嚴禁遞歸計算階乘 (棧溢出、重複計算、無尾調用優化)。
- 上一篇文章: Java算法實例:分數序列 2/1, 3/2, 5/3, 8/5... 前20項求和
- 下一篇文章: Java 遞歸計算階乘:5! 遞歸實現與棧幀分析
Copyright ©
程式碼之家 All Rights Reserved