大数运算

所谓的高精度运算,是指参与运算的数(加数,减数,因子……)范围大大超出了标准数据类型(整型,实型)能表示的范围的运算。例如,求两个200位的数的和。这时,就要用到高 精度算法了。在这里,我们先讨论高精度加法。高精度运算主要解决以下三个问题:

基本方法

1、加数、减数、运算结果的输入和存储
运算因子超出了整型、实型能表示的范围,肯定不能直接用一个数的形式来表示。能表示多个数的数据类型有两种:数组和字符串
(1)数组:每个数组元素存储1位(在优化时,这里是一个重点!),有多少位就需要多
少个数组元素;
用数组表示数的优点:每一位都是数的形式,可以直接加减;运算时非常方便
用数组表示数的缺点:数组不能直接输入;输入时每两位数之间必须有分隔符,不符合数
值的输入习惯;

(2)字符串:字符串的最大长度是255,可以表示255位。
用字符串表示数的优点:能直接输入输出,输入时,每两位数之间不必分隔符,符合数值
的输入习惯;
用字符串表示数的缺点:字符串中的每一位是一个字符,不能直接进行运算,必须先将它
转化为数值再进行运算;运算时非常不方便;
(3)因此,综合以上所述,对上面两种数据结构取长补短:用字符串读入数据,用数组存
储数据:

#include <stdio.h>
#include <assert.h>
#include <string.h>
#define max_strlen 100
void convert(char *num)
{
	assert(num!=NULL);
	int strlent=strlen(num);
	int temp=0;
	for (int i=0;i<=(strlent-1)/2;i++)
	{
		temp=num[i];
		num[i]=num[strlent-1-i];
		num[strlent-1-i]=temp;
	}

}
void addbig(const char *num1, const char *num2,char *result)
{
	assert(num1!=NULL && num2!=NULL);
	char *num11=(char*)num1;
	char *num22=(char*)num2;
	int len1=strlen(num1);
	int len2=strlen(num2);
	convert(num11);
	convert(num22);
	int len=(len1>=len2)?len1:len2;
    int ret[max_strlen];
	memset((void*)ret,0,max_strlen*sizeof(int));

	for (int i=0;i<len;i++)
	{
		if (i>=len1)
		{
			num11[i]='0';
		}
		if (i>=len2)
		{
			num22[i]='0';
		}
		ret[i]+=(int)(num11[i]-'0')+(int)(num22[i]-'0');
		if (ret[i]>=10)
		{
			ret[i]=ret[i]%10;
			ret[i+1]++;
		}
	}

	if (ret[len]==1)
	{
		len=len+1;
	}
	for (int j=len-1;j>=0;j--)
	{
		result[len-1-j]=*((char*)(ret+j))+'0';
	}

}
void main()
{
    char n1[100]="23463367805678967878945";
	char n2[100]="23568484567476567";
	char result[100]="";
	addbig(n1,n2,result);
	puts(result);

}

 

其中,有几点需要注意的地方:

1,void *memset( void *dest, int c, size_t count );  count:Number of characters,所以当内存区域存放的是整型时,需要写为len*sizeof(int),才能将这一块内存区域置0.

2,if (i>=len1)
  {
   num11[len1-1-i]='0';
  }

是为了防止当i>=len1时,num[11]='\0 ',ASCII码的值为零,并不是字符'0',要注意区分!!! 

3,将数字转化成为字符串时,要加‘0’。

4,convert函数是将字符串反转,不然的话,如果不反转,从最后一个数开始,一直往前的话, 要判断字符串是否结束,否则就会出现字符串越界的现象。

 

 

 

 

 

 

 

 

 

 

 

 

附:栈中能操作的一段称为栈顶,不能操作的一段称为栈底,栈是由高地址向低地址生长的,所以栈底的地址要高于栈顶的地址。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值