大数思维-大数阶乘(1000以内)(c++描述)

首先,在本篇文章开头提供我看到的挺好的阶乘解法(c描述)的链接:https://blog.csdn.net/lisp1995/article/details/52403507

我的解法也是参考他的思路的.
众所周知,普通的阶乘100以内(或者更小),我们是可以直接算的(简单的迭代或者递归),但当超过一定的long long int(64位)范围,就会溢出,这时我们就不能直接通过定义变量来求了,这时所求的数我们就该叫做大数了,一说到大数,我们就不是从变量的角度出发了,而是从数组的角度出发,采用最原始的人工计算方法,而且数组元素是用来做位数的,每一个元素做一位,从而能够存储更大范围的数。

注意一下,在这里我们首先要知道要求的范围内最大的数的阶乘的位数,以便为数组申请空间,我百度了一下:https://baike.baidu.com/item/%E9%98%B6%E4%B9%98/4437932?fr=aladdin
公式在应用那里:n! = 10^M ->lg n! = M -> lg1+lg2+lg3+lg4+…+lgn = M
直接循环求值就可以知道位数了,我求得1000!的位数是2567.6也就是2568位

emmm,好了,开始解释阶乘求法

我们首先申请一定的数组空间,
我们令a[0] 等于1作为初始值,dig作为位数 ,为1,temp 是临时值,用来存放某个位上的数的乘积
比如
因为a[0] = 1
刚开始的时候 设进位的数 num为0
temp = a[0]*2 +num=2
a[0] = temp%10 = 2
num =temp/10=0 显然是符合的 因为乘以2的时候是没有进位
接下来是a[0]*3 类似上面
接下来是a[0]*4
此时 temp = a[0]*4+num = 24 也就是 个位是 4 十位 是2
所以
a[0] = temp%10 = 4 a[1] 来存 2 也就是 num=temp/10
刚刚我们在设置位数的时候只是一位 所以 num还保存着向前进的数 ,所以在外面加个循环用于将上一次求得最后的num(num>0)向前进位保存
(该方法是模拟竖式乘法
0 6
x 4
——
2 4
你可以通过用笔计算来模拟。)
接下来是a[0]*5 ,a[1]*5+num
也就是 24x5 相当于 4x5 = 20 向前进2 本位是0 代码操作temp = a[0]{4} x 5+num(每次新乘一个数的时候 num都会初始化为0) 所以 temp = 20
那么a[0] = temp%10 = 0 刚好符合了本位的数是0 num = temp/ 10=2
刚好符合向前进的数是 2
然后就是2x5 = 10 加上之前4x5进的数 2 就是12 所以temp = 12
所以保存在本位 的是 2(12%10) 向前进一位 是 1
所以用a[2]存上一位的进的数 1
所以此时逆过来输出(a[2]a[1]a[0] )是不是 120
…后面的计算都是类似这样的

参考代码
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
 int a[2600];
 int temp,dig,n,num;//temp  是一个临时的值,用来存放的是每一位计算的结果 dig 是位数
 //num是上一位所向前进的数
 cin >> n; 
 a[0] = 1;//初始化个位的数为 1 
 dig = 1; //位数是 1(刚开始的时候)
 for(int i = 2;i <= n;++i )
 {
 	num = 0; //刚开始的时候 num的值是 0
 	//以位数来循环求值 dig是位数 刚开始的时候是1 
 	for(int j = 0;j < dig;++j)
 	{
 		/*temp 用来存放某个位上的乘积(模拟竖式乘法单独位数相乘)加上 上一位位数 求得所向下一位数(数学中称满10进1)进的数*/
 		temp = a[j]*i+num;  
 		a[j] = temp%10;  //记得满10进1的原则  也就是对10求余的数才是本位保留的数 是10的倍数的是要进位 
 		num = temp /10; //进位 
 	} 
 	// 检查num是否是大于0 如果大于0 则说明还得向前进位
 	while(num)
 	{
 		a[dig] = num%10;
 		num/=10;
 		++dig;
 	} 	
 }
 //高位是在后面的 逆回来读 
 for(int i = dig -1;i >= 0;--i)
 {
 	printf("%d",a[i]);  
 	
 	
 }
 return 0;
}
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值