计算阶乘的Rsum求和代码在大数值范围输出为0的问题求助
问题分析
你的代码在处理大数值范围(如41-49)时输出0,核心原因有两个:
- 整数溢出:
int类型的最大值通常为2147483647,而13! = 6227020800已经超过这个范围,后续计算阶乘时会溢出,导致factorial变成负数或无意义的0值,后续的各位求和逻辑自然出错。 - 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; }
若坚持计算阶乘的替代方案
如果一定要通过计算阶乘来实现,需要:
- 使用更大的数据类型(如
unsigned long long)存储阶乘,延迟溢出的发生(但unsigned long long最多能存到20!,超过20!还是会溢出) - 正确实现迭代求和到个位数的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
相关产品推荐
相关产品推荐

