如何修改C语言阶乘代码以输出后续阶乘值(当前仅到33停止)
解决C程序计算阶乘时33!后溢出的问题
问题描述
当前程序计算到33的阶乘时输出结果出现异常(实际是整数溢出),无法正确输出更大的阶乘值(比如到100!)。原代码使用int类型存储阶乘结果,但33!的数值已远超32位int的最大值(约2.1×10^9),导致溢出后输出错误值。
原代码如下:
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #define MAX_FACTORIALS 10000 #define NUM_FACTS 100 struct FactorialResults { int results[MAX_FACTORIALS]; int numResults; }; int factorial(const int n) { return (n > 1) ? n * factorial(n - 1) : 1; } void computeFactorials(struct FactorialResults *results, int numFactorials) { int i; for (i = 0; i < numFactorials; i++) { results->results[i] = factorial(i); } results->numResults = numFactorials; } int main(void) { struct FactorialResults results = {{0}, 0}; int i; computeFactorials(&results, NUM_FACTS); for (i = 0; i < NUM_FACTS; i++) { printf("%5d %12d\n", i, results.results[i]); } return 0; }
修改方案
要计算大数阶乘,必须用数组模拟大整数乘法,普通数值类型无法容纳超大的阶乘结果。以下是修改后的完整代码:
修改思路
- 用数组的每个元素存储阶乘结果的一位数字(低位在前,方便处理进位)
- 基于前一个数的阶乘结果计算当前数的阶乘:
n! = (n-1)! × n,逐位执行乘法并处理进位 - 单独记录每个阶乘结果的有效位数,确保输出正确
修改后的代码
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #define MAX_DIGITS 10000 // 足够容纳100!的位数(100!共158位) #define NUM_FACTS 100 // 存储单个阶乘的大数结果和有效位数 struct FactorialResults { int digits[MAX_DIGITS]; // 低位在前存储每一位数字 int length; // 当前阶乘结果的有效位数 }; // 计算0!到numFactorials!的所有结果 void computeFactorials(struct FactorialResults results[], int numFactorials) { // 初始化0! = 1 results[0].digits[0] = 1; results[0].length = 1; for (int n = 1; n < numFactorials; n++) { // 复制前一个阶乘的结果到当前数组 for (int i = 0; i < results[n-1].length; i++) { results[n].digits[i] = results[n-1].digits[i]; } results[n].length = results[n-1].length; // 执行乘法:当前结果 × n int carry = 0; for (int i = 0; i < results[n].length; i++) { int product = results[n].digits[i] * n + carry; results[n].digits[i] = product % 10; // 保留当前位 carry = product / 10; // 计算进位 } // 处理剩余进位 while (carry > 0) { results[n].digits[results[n].length] = carry % 10; carry /= 10; results[n].length++; } } } // 输出指定阶乘的结果(从高位到低位打印) void printFactorial(int n, struct FactorialResults *result) { printf("%5d: ", n); // 从数组末尾(高位)开始打印 for (int i = result->length - 1; i >= 0; i--) { printf("%d", result->digits[i]); } printf("\n"); } int main(void) { struct FactorialResults results[NUM_FACTS] = {0}; computeFactorials(results, NUM_FACTS); for (int i = 0; i < NUM_FACTS; i++) { printFactorial(i, &results[i]); } return 0; }
代码说明
- 结构体调整:原结构体存储单个
int结果,现在改为存储大数的数字数组和有效长度,每个阶乘对应一个结构体实例。 - 大整数乘法:
- 初始化0!为1作为基础
- 每个
n!基于(n-1)!计算,逐位乘以n并处理进位,确保每一位都在0-9范围内 - 剩余进位会被依次添加到数组末尾,更新有效长度
- 输出逻辑:由于数组是低位在前存储,输出时从最后一位(高位)开始打印,才能得到正确的数字顺序。
修改后程序可正确计算并输出0!到100!的所有结果,不会因整数溢出出错。
内容的提问来源于stack exchange,提问作者Kes
相关产品推荐
相关产品推荐

