You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改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;
}

代码说明

  1. 结构体调整:原结构体存储单个int结果,现在改为存储大数的数字数组和有效长度,每个阶乘对应一个结构体实例。
  2. 大整数乘法:
    • 初始化0!为1作为基础
    • 每个n!基于(n-1)!计算,逐位乘以n并处理进位,确保每一位都在0-9范围内
    • 剩余进位会被依次添加到数组末尾,更新有效长度
  3. 输出逻辑:由于数组是低位在前存储,输出时从最后一位(高位)开始打印,才能得到正确的数字顺序。

修改后程序可正确计算并输出0!到100!的所有结果,不会因整数溢出出错。

内容的提问来源于stack exchange,提问作者Kes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 17:04:50