C语言中如何实现对超大数据的存取与运算

2 篇文章 0 订阅

方法一:

对于超大的整型来说 int .     long .    long long.  都在存储范围上边无能为力  ,此时我们可以想到浮点数据类型 float.  double 

但是当我们 我们要计算一下1000!中含有多少个数字2的时候

首先我们当是100!时候

#include<stdio.h>
#define N 100
 int main()
{
	double sum=1.0;int count=0;
	
	for(int i=1;i<=N;i++)
	{
		sum*=i;;
	}
	while(sum/sum-1)//在这里我因为真正当sum/2用来计算所耗时间过长,所以这里我将2用sun-1替换了
	{
		
		count++;
	}
	printf("%lf\n含有%d个\n",sum,count);
	
	return 0;
	
}
这个结果如下,但是不是精确的,这是已经舍弃之后的数

  下来当是200!时候

#include<stdio.h>
#define N 1000
int main()
{
	double sum=1.0;int count=0;
	
	for(int i=1;i<=N;i++)
	{
		sum*=i;;
	}
	while(sum/sum-1)//在这里我因为真正当sum/2用来计算所耗时间过长,所以这里我将2用sun-1替换了
	{
		
		count++;
	}
	printf("%lf\n含有%d个\n",sum,count);
	
	return 0;
}

很明显超出了范围,所以用浮点数只能表示一定范围的数,至少100!表示不了,那怎么存储1000!呢?

 哈哈! 我们也可以用数组存储呀!

   这里关键要考虑到进位存储在搞标号的数组单元中

/**********************************************************************  
* Copyright (c)2015,WK Studios
* Filename:    
* Compiler: GCC,VS,VC6.0  win32  
* Author:WK  
* Time: 2015 4 18
************************************************************************/ 
#include<stdio.h>
#define Ma 10000   //a的最大容量,必须大于na
int pa=0;//指向数组a的有效末端
int p=2;//求阶乘时的当前乘数
unsigned int carry=0;
int memory_over=0;

union data
{   //表示范围0--2^32-1
	unsigned long int b;//这里也可以用数组usigned long int ,但是用公用体可以存储不同类型的数据
}a[Ma];

void main()
{
	unsigned int n;//求n的阶
	void facto(unsigned int n);
	printf("Input n:");
	scanf("%u",&n);  
	
	a[0].b=1;//初始化
	facto(n);//测试后至少可以计算10000!
	
	if(memory_over==0)
	{
		printf("the result include %dNO:\n",pa+1);//高位输出
		printf("%u",a[pa--].b);
		for(;pa>=0;pa--)
		{
			printf("%04u",a[pa].b);//04%d用来补充0限制每个int型中存放4位数
		}
		printf("\n");
	}
	getchar();
}




void facto(unsigned int n)
{
	void multiple();
	pa=0;        
	while(pa< Ma-1 && p<=n)//容量限制
	{
		multiple();
		p++;//每一轮乘一个阶数p
	}
	if(p<=n)//此时pa>=Ma-1退出while循环说明超出数组所能存储的范围
	{
		printf("memory out!\n");
		memory_over=1;
	}//如果当前的存储结果的数组a[Ma]不够用!应提高Ma
	
}

void multiple()
{
	int i=0;
	carry=0;
	while(i<=pa)//i指向当前处理的元素a[i],每一轮用一个位与阶数p相乘
	{
		a[i].b=a[i].b*p+carry;//计算结果,要考虑来自低位的进位
		carry=a[i].b/10000;//计算进位
		a[i].b=a[i].b%10000;//计算余数
		i++;
	}
        //储代码块后carry=0  
        if(carry>0)
		a[++pa].b=carry;
}




                         

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值