大数阶乘之大数存储方法

我们都知道计算机存储每一种数据类型都是有一定范围的,我们就拿int(在C语言中一般都占四个字节)来说,如果我们想用它存储某个整数,他存储的范围也只能存储-2^31(-2147483648) ~ 2^31-1(2147483647)之间的数,如果我们想存储更大的数就只能改变数据类型,修改成long或者long long,但是如果我们想存储比这个数还要大的数那又怎么办呢?你一定会说我存储这么大的数干嘛,又没有实际意义,对,确实,我们在实际生活中可能真的不会用到,但是,我们要知道,既然我们提出了这个问题,那么我们就有地方需要,当然,你又会问了,什么地方会用这么大的数,嘿嘿,你还真别说,我们还真经常得用。例如,我们需要计算某个数的阶乘的时候就会需要到。这个时候你又会说了,你在乱“yue”,我之前就没用,我就用int或者long long就可以了…兄弟,我就想问你,你求的数的阶乘是多大的?是10,还是20?在这些小数的阶乘下,基本数据类型确实可以,但是我们还是回到之前的问题,如果这个数大于了这个基本数据类型怎么办?叫你求1000,10000,甚至更大,你将会怎么办?我猜的没错的话,long long好像只能计算存储173的阶乘,174都不行,所以这个时候我们就必须换一种思路来存储我们的大数。没错,聪明的小伙伴已经想出办法来了,就是用数组来存储我们的大数。例如,我们要存储12345678这个数,我们可以把它放在一个大小为8的数组里面,a1到a9分别存储1到9的数字。这样不论多大的数字,我们都可以存储了(当然需要你的有足够大的空间)。是不是这个方法很好,当然,有基础的小伙伴就会想到这个会不会浪费空间啊,因为一个int本来可以大小为4个字节(32位)的数,我们却只存一个数字,也才用1个字节(8位),这样就浪费了3个字节(24位),没错,这样确实很浪费空间,所以,我们在接下来的计算中会存储10^5这样大的数,当然,也可以更大或者更小。好,说了这么多废话,接下来上干货。
#include<stdio.h>
#include<time.h> //计算时间头文件 
#define SIZE 9000  //数组大小,可以根据自己需要更改 

int main() {
	int n;
	long long start = 0,end = 0;//用于统计计算时间 
	int arr[SIZE]= {0};
	arr[SIZE-1] = 1;
	printf("请输入一个数: "); 
	scanf("%d",&n);
	start = clock();//开始时间 
	int sum = 1;
	for(int i=1; i<=n; i++) {
		int modify = 0;
		for(int j=SIZE-1; j>=0; j--){
			sum = arr[j] * i + modify;
			arr[j] = sum % 10000;
			modify = sum / 10000;
		}
		printf("%4d! = ",i);
		for(int k=0; k < SIZE; k++) {
			if(arr[k]!=0) {
				printf("%d",arr[k]);
				for(int j=k+1; j<SIZE; j++) {
					printf("%05d",arr[j]);//控制输出格式
				}
				break;
			}
		}
		printf("\n"); 
	}
	//结束时间
	end = clock();
	printf("\n总共消耗时间为:%lldms\n",end-start);
	return 0;
}

我先运行截图100的阶乘,因为时间比较仓促。
在这里插入图片描述

这个代码可以保证你计算2^31的阶乘没有问题(当然上面定义的SIZE,数组的大小需要修改一下,当然你也可以用relloc()函数来动态生成空间)。我上次计算一万的阶乘用学校的电脑跑了几十分钟,最后下课了,还没等他跑完就关了,后来我用平板测试,md直接把我的平板跑熄火了,在这里,大家不用怕,我平板跑熄火完全是由于平板本来就撇,不是代码原因,大家闲来无聊也可以试试十万的阶乘,说实话,当你看见控制台输出一串串数字的时候,你真的会感到自豪,作为程序员,你也肯定会感觉到数字的优美。当然,你也可以拿去吓唬你的室友,直接把里面的n赋值十万,将编译生成的.cpp文件发给他,让他用电脑打开…后面的就自己想把。

好的,今天的分享就到这里了。欢迎小伙伴留言关注。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值