首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言問答

C語言 while 迴圈計算 1×2×...×100 階乘:溢出與大數處理

     編輯:C 語言問答

基本實現(while 迴圈)

#include 

int main() {
    int i = 1;
    unsigned long long fact = 1; // 64位無符號,範圍 0 ~ 1.84e19
    while (i <= 100) {
        fact *= i;
        i++;
    }
    printf("100! = %llu\n", fact);
    return 0;
}

⚠️ **100! ≈ 9.33×10¹⁵⁷ 遠超 64 位整數範圍**,上述代碼會**靜默溢出繞回**,輸出錯誤結果。

正確輸出 100! 的三種方案

1. 任意精度庫 GMP(專業首選)


// 編譯: gcc -lgmp fact100.c
#include 
#include 

int main() {
    mpz_t fact;
    mpz_init_set_ui(fact, 1);
    for (int i = 2; i <= 100; i++)
        mpz_mul_ui(fact, fact, i);
    gmp_printf("100! = %Zd\n", fact);
    mpz_clear(fact);
    return 0;
}

2. 手寫大整數乘法(十進制數組模擬)


#include 
#define BASE 1000000000 // 10^9,每個元素存 9 位十進制
#define WIDTH 9
int a[500] = {1}; // 足夠存 100! (約 158 位十進制)

void mul_int(int *a, int m) {
    long long carry = 0;
    for (int i = 0; a[i] || carry; i++) {
        carry += (long long)a[i] * m;
        a[i] = carry % BASE;
        carry /= BASE;
    }
}

void print_big(int *a) {
    int i = 499;
    while (i > 0 && a[i] == 0) i--;
    printf("%d", a[i--]);
    for (; i >= 0; i--) printf("%0*d", WIDTH, a[i]);
    puts("");
}

int main() {
    for (int i = 2; i <= 100; i++) mul_int(a, i);
    print_big(a);
    return 0;
}

3. Python/BC 快速驗證


# Python
import math
print(math.factorial(100))

# bc (Linux 計算器)
echo 'define f(x) { if (x<=1) return 1; return x*f(x-1) }; f(100)' | bc

while 迴圈關鍵點總結

點說明
初始化int i = 1; fact = 1; 必須在迴圈前
條件i <= 100 含邊界
更新i++ 在迴圈體末尾(或開頭配合 continue)
等價 forfor (int i=1; i<=100; i++) fact *= i; 語義更集中
溢出檢測無符號溢出定義為模 2⁶⁴,需手動檢查 if (fact > ULLONG_MAX / i) overflow

總結

  • **while 迴圈計算階乘語法正確,但 100! 必須用大整數**。
  • **GMP 庫** 是工業界標準,**手寫大整數** 是面試/教學必會,**Python** 是快速驗證工具。
  • 若題目僅要求「寫 while 迴圈」,說明溢出風險並給出大數方案即為完美答案。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved