关于高精度阶乘问题
关于阶乘,正常情况来讲,在数很小的范围内可以计算,并且可以使用较高范围的数据类型来进行存储数据。
10!=3628800
11!=39916800
12!=479001600
13!=6227020800(10位数字)
而 int 数据类型的取值范围为 -2147483648 ~ 2147483647(10位数字)
从13!开始,具体结果已经不能用int表示了。所以用int数据类型计算阶乘,最多可以计算到12!。
如果用long数据类型计算。
首先要知道long数据类型的取值范围为
-9223372036854775808 ~ 9 223 372 036 854 775 807(19位数字)
20!= 2432902008176640000(19位数字)
21!= 5.1090942171709e+19
很明显从21!开始,具体结果已经不能用long数据类型表示了。
提示:以下是本篇文章正文内容,下面的解法仅供参考
一、怎么处理数据溢出问题?
C/C++中可以用数组来存放大量的数据,所以用数组来实现大数据的存放,将数组的每一位分别对应结果的每一个数位,在每一位上进行数据的乘法以及进位问题。
二、实现高精度阶乘
1.思路分析
- 首先定义一个数组(num[1000])来存放结果的每一位
num[0] | 代表着这个阶乘结果有多少位 |
---|---|
num[1] | 个位数 |
num[2] | 十位数 |
num[3] | 百位数 |
… | … |
num[999] | 不一定用到 |
然后进行每一位的计算处理,核心处理为:
将数组从 1 开始,计算阶乘过程中的每一步乘法运算
第一次将 num[0] 赋值为 1,含义为代表着乘法运算从个位开始
每一次运算将本位数存放到本位数组元素中,将进位数存放到下一个数组元素中。
for(int i = 1; i <= num[0]; i++){
num[i] = num[i] * n + temp; //temp 代表着进位数
temp = num[i] / 10; //代表着将进位的数保存到 temp 中
num[i] = num[i] % 10; //本位只保留乘法运算后的个位数即可
}
while(temp){
num[0]++; //如果 temp 不为 0,则说明该数进位了,在原来的基础上多进了一位
num[num[0]] = temp % 10; //将进的数保存在下一个数组元素中
temp = temp / 10;
}
最后将数组倒序输出就OK了
for(int i = num[0]; i >= 1; i--){
cout << num[i];
}
2.代码实现
代码如下(示例):
void Factorial(int n){
int n;
cin >> n;
int num[100000];
num[0] = 1;
num[1] = 1;
for(int i = 2; i <= n; i++){
int temp = 0; //temp 代表着进位数
for(int j = 1; j <= num[0]; j++){
num[j] = num[j] * i + temp;
temp = num[j] / 10; //代表着将进位的数保存到 temp 中
num[j] = num[j] % 10; //本位只保留乘法运算后的个位数即可
}
while(temp){
num[0]++; //如果 temp 不为 0,则说明该数进位了,在原来的基础上多进了一位
num[num[0]] = temp % 10; //将进的数保存在下一个数组元素中
temp = temp / 10;
}
}
cout << n << "!=";
for(int i = num[0]; i >= 1; i--){
cout << num[i];
}
}