大数阶乘
我们通常使用的数据类型比如 int 、float 等都是有范围的,如果我们要计算的数据远超出它们所表达的范围,该怎么办?答案是使用 数组 来完成计算。
1. 大数阶乘
1.1 算法说明
不管是计算过程中的中间数据还是结果数据,我们都用图 1.1 所示的方式保存在数组中,数组从左向右填充,每个数组元素保存大数的一位,下标小的保存低位,下标大的保存高位。
当我们需要将计算所得的大数输出时,从数组的末端开始向头部扫描,遇到第一个不为 0 的数开始输出。如果需要一次性将结果输出,可以将每个数组元素转为字符串,将字符串连接即可。
现在说最关键的一步——计算,假设我们现在已经有 10!的一个数组,想要计算 11! ,该如何操作?
3628800 = 3000000 + 600000 + 20000 + 8000 + 800 + 0 + 0
3628800 * 11 = (3000000 + 600000 + 20000 + 8000 + 800 + 0 + 0) * 11
= 3111000000 + 611100000 + 21110000 + 8111000 + 811100 + 0 + 0
= 331000000 + 66100000 + 2210000 + 881000 + 88*100 + 0 + 0
但是我们的要求是不管中间结果还是最终结果,我们的每一个数组元素都只保存大数的一位,所以我们现在把低位的进位给高位。
a[0] 、a[1] 无进位;
a[2] 的进位为 8,剩余 8,a[2] = 8;
a[3] 拿到 a[2] 的进位变为 96,进位为 9,余 6,a[3] = 6;
同理可得 a[4] = 1,a[5] = 9,a[6] = 9,a[7] = 3。
因此,整个算法的设计思路就是用数组中的每一个元素分别乘上一个数,再将低位产生的进位传递给高位。
比如 4! = 432*1,我们的做法就是首先将数组的所有元素设置为 0,然后 a[0] = 1,接下来就是用数组中的每个元素乘上2,计算进位,再乘3,计算进位,再乘4,计算进位,结束。
1.2 示例代码
#include <stdio.h>
#include <