高精度加法 高精度减法 高度除法 高精度乘法 方法总结

一.引言

        对于数字的储存,用实数类型总会有一些不足,比如:

                使用int 只能最多存储4个字节,范围也就是2的32次方;

                使用double 只能最多储存8字节,就是2的64次方;

        如果数字超过这个限制,就会发生溢出,导致结果错误。那么我们该如何解决呢?

        为了解决这个问题,我们就要回归到我们小学所学的知识  :   

                                                                            列式计算

二.一般步骤:

        1.高精度加法:

                a.将字符组转化为数组(注意顺序问题,影响到后续计算)

                b.计算是否进位,如果进位则下一个结果项加上进位数

                c.将两个数组各项以及进位相加,得到结果的数组

               d.按顺序输出(顺序取决于第一步的顺序)

PS:减法只是将进位换位借位,大体不变       

        2.高精度减法: 

               a.提前开一个数组,以存放未除尽的的的数

                b.将字符组转化为数组(注意顺序问题,影响到后续计算)

                c.用除法结果作为这一位的结果,用求余来放到开的数组里

                d.按顺序输出(顺序取决于第一步的顺序)

PS:这个说的有点抽象,具体可参考第二个例题

        3.高精度乘法乘法:

                a.提前开一个数组,以存乘积后的的的数

                b.将字符组转化为数组(注意顺序问题,影响到后续计算)

                c.需要注意乘法的数组长等于两个相乘数组长度之和

                c.乘法结果作为这一位的结果,放到开的数组里

                e.如果大于10,对10的余数加到下一位,这一位留下除以10的值

                d.按顺序输出(顺序取决于第一步的顺序)

       

三.例题

1.高精度加法:

        首先看一个代码,这是早期人类初步接触高精度加法时的 “ 作品 ” :

高精度加法 高精度减法 高度除法 高精度乘法 方法总结_第1张图片

                        


#include
using namespace std;

int main()
{
	char a[100],b[100];

//用于记录2个高精度数的每一位

	char aa[100],bb[100];
	
//后期用于储存没有前导零的字符组

	for(int i=0;i<100;i++)
	{
		aa[i]=bb[i]='0';
	}
	int m=0,n=0;
    int sum=0,sum_=0;

//标记2个字符组的位数

    char x;
	while((x=getchar())!='\n')
	{
		a[m]=x;
		m++;
	} 
	while((x=getchar())!='\n')
	{
		b[n]=x;
		n++;
	} 

//输入两字符组

	int a_=0,b_=0;
	int c_=max(m,n);

//a_,b_代表处理过前导零后的位数
//c_代表两者字符组所含更大的位数

	for(int i=0;i=m)
		continue;
		else 
		{	
			aa[a_]=a[i];
			sum_++;
			a_++;
	
		}
	}
	reverse(aa,aa+a_);		
	for(int i=0;i=n)
		continue;
		else 
		{
			bb[b_]=b[i];
			sum++;
			b_++;
		}
	}

//去除前导零,比如:008->8

	reverse(bb,bb+b_);

//反转操作,将顺序调整

	int ma=max(sum,sum_);	
	char k[101];
	int st=0;

//st代表进位

	for(int i=0;i=0;i--)
	{
		cout<

        这个代码的问题有以下几点

                1.处理前导零的时间过早,导致步骤冗杂

                2.没有第一时间将字符组转化为数组

                3.对字符组中字符的顺序没有处理好,导致顺序错乱,使代码凌乱

2.高精度加,乘,除

        再看一个比较简洁的代码,这个已经解决了如上的问题,并按照正常顺序书写:

高精度加法 高精度减法 高度除法 高精度乘法 方法总结_第2张图片

首先用等差数列求和计算出 n*(n+1)/2

所以,先计算n+1:

for(int i=0;i0) len++;

 然后,计算n*(n+):

for(int i=0;i=10)
			{
				c[k+1]+=c[k]/10;
				c[k]%=10;
			}
			
		}
	}
	len=s1.length()+len+1;
	if(c[len]>0) len++;
	while(c[len-1]==0&&len>1) len--;
	
//去首位的0 

一定要注意谁对应 i,谁对应 j ,笔者因为这个问题调试了半个小时。

最后,计算除2的值: 

 int t=0;
	for(int i=len-1;i>=0;i--)
	{
		d[i]=(c[i]+t)/2;
		t=c[i]%2*10;
	} 
	while(d[len-1]==0&&len>1) len--;

//去除前导零

	for(int i=len-1;i>=0;i--)
	{
		cout<

拼接起来组成完整代码: 

#include
#include
using namespace std;

int main()
{
	string s1;
	int a[105]={0},b[105]={0},c[205]={0},d[205]={0};
	cin>>s1;
	int len=s1.length();
	for(int i=0;i0) len++;
	
//注意部位 
	
	for(int i=0;i=10)
			{
				c[k+1]+=c[k]/10;
				c[k]%=10;
			}
			
		}
	}
	len=s1.length()+len+1;
	if(c[len]>0) len++;
	while(c[len-1]==0&&len>1) len--;
	
//去首位的0 
	
    int t=0;
	for(int i=len-1;i>=0;i--)
	{
		d[i]=(c[i]+t)/2;
		t=c[i]%2*10;
	} 
	while(d[len-1]==0&&len>1) len--;
	for(int i=len-1;i>=0;i--)
	{
		cout<

其实,高精度唯一需要注意的两点就是:

                1.注意进位和借位

                2.注意字符组中的顺序

注意到这些,再多加练习,就可以想写低精度加法一样顺利了。 

以上就是今天分享的内容了,希望对有需求的码友有帮助。

你可能感兴趣的:(c++,算法)