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

计算阶乘的Rsum求和代码在大数值范围输出为0的问题求助

问题分析

你的代码在处理大数值范围(如41-49)时输出0,核心原因有两个:

  1. 整数溢出:int类型的最大值通常为2147483647,而13! = 6227020800已经超过这个范围,后续计算阶乘时会溢出,导致factorial变成负数或无意义的0值,后续的各位求和逻辑自然出错。
  2. Rsum实现不完整:题目要求迭代求和到个位数,但当前代码仅计算一次各位数字之和,若该和仍为两位数,就无法得到正确的个位数结果(比如如果阶乘的各位和是19,代码会返回10而非1)。

另外,直接计算大数阶乘既浪费计算资源,又容易触发溢出,完全可以通过数学规律简化逻辑。

解决方案

利用数字根与阶乘的数学规律简化计算

题目中的Rsum本质是数字根,数字根有明确的数学公式:

  • 若数字为0,数字根为0
  • 否则,数字根 = 数字 % 9;若结果为0,则数字根为9(除了0本身)

而阶乘的数字根存在固定规律:

  • 0! = 0 → 数字根0
  • 1! = 1 → 数字根1
  • 2! = 2 → 数字根2
  • 3! = 6 → 数字根6
  • 4! = 24 → 数字根6
  • 5! = 120 → 数字根3
  • 当n ≥6时,n!包含因子9(比如6! = 720,包含2×3×3),所以数字根恒为9

基于这个规律,我们可以直接根据输入的数值返回对应的数字根,完全不需要计算大数阶乘,彻底避免溢出问题。

修正后的代码

#include <stdio.h>

int get_rsum_of_factorial(int n) {
    if (n == 0) return 0;
    switch(n) {
        case 1: return 1;
        case 2: return 2;
        case 3: return 6;
        case 4: return 6;
        case 5: return 3;
        default: return 9; // n >=6时,阶乘的数字根都是9
    }
}

int main() {
    int range1, range2;
    printf("enter the range of the number:");
    scanf("%d %d", &range1, &range2);
    
    int total = 0;
    for (int j = range1; j <= range2; j++) {
        total += get_rsum_of_factorial(j);
    }
    
    printf("%d\n", total);
    return 0;
}

若坚持计算阶乘的替代方案

如果一定要通过计算阶乘来实现,需要:

  1. 使用更大的数据类型(如unsigned long long)存储阶乘,延迟溢出的发生(但unsigned long long最多能存到20!,超过20!还是会溢出)
  2. 正确实现迭代求和到个位数的Rsum逻辑

示例代码:

#include <stdio.h>

int calculate_rsum(unsigned long long num) {
    if (num == 0) return 0;
    int sum;
    do {
        sum = 0;
        while (num > 0) {
            sum += num % 10;
            num /= 10;
        }
        num = sum;
    } while (sum >= 10);
    return sum;
}

unsigned long long calculate_factorial(int n) {
    if (n == 0) return 0;
    unsigned long long fact = 1;
    for (int k = 1; k <= n; k++) {
        fact *= k;
        // 提前判断是否溢出,若溢出直接返回(因为n>=21时unsigned long long也存不下)
        if (fact / k != fact / k) {
            return 0;
        }
    }
    return fact;
}

int main() {
    int range1, range2;
    printf("enter the range of the number:");
    scanf("%d %d", &range1, &range2);
    
    int total = 0;
    for (int j = range1; j <= range2; j++) {
        unsigned long long fact = calculate_factorial(j);
        int rsum;
        if (fact == 0 && j != 0) {
            // n>=21时,阶乘溢出,根据规律数字根是9
            rsum = 9;
        } else {
            rsum = calculate_rsum(fact);
        }
        total += rsum;
    }
    
    printf("%d\n", total);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 08:10:09