这个问题是一个朋友聊天的时候突然聊到,在计算C语言中如何计算大数的阶乘。
10!在C语言完全没问题,但是如果是100!1000!的话如何实现。当时我不加思索给出下的代码:
//大数的阶乘 100! 错误
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int i;
int N = 0;
int factorial = 1;
printf("请输入你要的求的阶乘数N\n");
scanf("%d", &N);
for (i = 1; i <= N; i++)
{
factorial = factorial*i;
}
printf("%d!=%d",N,factorial);
system("pause");
return 0;
}
我输入小数时,结果是没有问题的,但是当我计算100!的时候,发现100!居然是0.这个时候我意识到是不是100!超过我设置的数据类型的范围。但是我发现在C语言中并没有一个数据类型可以容纳100!那么如何解决这个问题了。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void factorial(int n, char *pout)
{
if (pout == NULL)
{
return;
}
int arr[256];
int idx = 1;
arr[0] = 1;
//此处要注意 i从1开始
for (int i = 1; i <= n; i++)
{
//cry用来记录进位
int cry = 0;
// idx记录现在有多少位 挨个相乘
for (int j = 0; j < idx; j++)
{
arr[j] = arr[j] * i + cry;
//此处用倒序存储
cry = arr[j] / 10;
arr[j] %= 10;
}
//如果进位大于10 要降级
while (cry > 10)
{
arr[idx++] = cry % 10;
cry /= 10;
}
//进位到这里如果还大于 0 证明位数要加1
if (cry > 0)
arr[idx++] = cry;
}
//将数组倒序赋值给字符串
for (int i = idx - 1; i >= 0; i--)
{
*pout++ = arr[i] + '0';
}
*pout = '\0';
return;
}
int main()
{
char buff[255] = {0};
int n = 0;
printf("input n:");
scanf("%d", &n);
factorial(n, buff);
puts(buff);
return 0;
}
算法分析:
100
!
=
100
∗
99
∗
98
∗
.
.
.
∗
1
100!=100*99*98*...*1
100!=100∗99∗98∗...∗1
这个类型于小学计算的乘法高位等于低位的本身×被乘数加低位的进位。这个时候本身就是对得到的数求余数,进位就是对除运算。