n! = 1 × 2 × ... × n,0! = 1。結果增長極快,13! 超過 32 位整數範圍,21! 超過 64 位。
#include <stdio.h>
#include <stdint.h>
int main() {
int n;
printf("請輸入非負整數 n:");
if (scanf("%d", &n) != 1 || n < 0) return 1;
uint64_t fact = 1; // 64 位無符號,支援至 20!
for (int i = 2; i <= n; ++i) {
fact *= i;
}
printf("%d! = %llu\n", n, fact);
return 0;
}
uint64_t fact_rec(int n) {
return (n <= 1) ? 1 : n * fact_rec(n - 1);
}
// 注意:遞迴深度受限於堆疊,n > 10^5 會棧溢位,階乘 n 通常很小故可接受
C 無內建大整數,需手寫或用庫(GMP)。陣列模擬十進制位:
// 簡易大整數乘法:以 10^4 為基數
#define BASE 10000
int a[1000] = {1}; // 存儲結果,最低位在 a[0]
int len = 1;
void multiply(int n) {
long long carry = 0;
for (int i = 0; i < len; ++i) {
carry += (long long)a[i] * n;
a[i] = carry % BASE;
carry /= BASE;
}
while (carry) {
a[len++] = carry % BASE;
carry /= BASE;
}
}
void printBigInt() {
printf("%d", a[len-1]);
for (int i = len-2; i >= 0; --i) printf("%04d", a[i]);
putchar('\n');
}
| 陷阱 | 現象 | 對策 |
|---|---|---|
用 int 存結果 | n≥13 溢位,結果為負/亂碼 | 用 uint64_t(至 20!)或大整數 |
| 未處理 n=0 | 迴圈不執行,結果正確(初值 1) | 明確處理或依賴初值 |
| 輸入負數 | 無意義 | 輸入驗證 n >= 0 |
printf("%d", fact) 格式錯誤 | 輸出錯誤 | %llu 對應 unsigned long long |