C++ 大数加法

        所谓大数加法就是说能够对超长位数的数字进行相加,比如一个100位数加一个90位数,为什么这会是一个问题呢?直接用int,long这些表示两个数,然后相加不行吗?肯定是不行滴~这些基本类型能处理的范围是有限的,因此如果你用一个int型变量来表示一个100位数,虽然不会报错,但是你将得不到正确的运行结果,因此数字被截断了,就好像你有一个书包,它能装10本书,你要用它来装100本书,肯定是装不下的,只能装10本,剩下的90本相当于被截断了,装不下了,丢弃了。要实现大数加法,一个简单的思路就是用字符串模拟数字,因为一个字符串可以很长很长,只要内存足够,但是对于int,long等这些类型,它们每一个的长度都定下来了,就算你内存再大,也只能说是装下很多个int或long而已,不能装下一个“长长的”它们,继续上面书包的例子,字符串类型就相当于你有一个可以扩容的书包,但发现装不下了,就扩容,书包就变大了,而int,long等这些基本类型是不能扩容的书包,每个书包装的容量是固定的。

       下面给出我的基本思路:

       按从低位到高位的顺序两个数字的每一位对应相加,并加上低一位的进位(如果有进位的话),如果某一位对应的数字加起来大于10,就对10取模得到当前位上的数字,再向高位进1,然后再考虑更高一位数字的相加,依次类推,如果位数较长的那个数字的最高位还有进位,别忘记了位数还要增加1。

       我下面用一些图展示其过程,图中是直接用其中一个数存储计算的结果,当然存储在一个新的空间也是可以的,根据需要选择。例如198+17:


        下面再给一个简单例子展示一下加完之后位数变多的情况,比例98+17:


       下面给出用我的C++实现的大数加法,程序中给的是10进制加法的实现,但可以非常非常容易的改为其它进制的加法,只需要在取模的那几步,把对谁取模改一下就行了,对10取模就说明每位数字不能超过10,自然就是10进制咯~

#include <iostream>
#include <string>
using namespace std;
string plus(string num1,string num2){
	if(num1.size()<num2.size()){//把num1固定为位数较大的那个数,方便后面处理
		string temp=num1;
		num1=num2;
		num2=temp;
	}
	int length1=num1.size(),length2=num2.size(),flag=0,a,b,sum;//flag是进位标记
	while(length1>0){//从低位开始把对应的位相加
		a=num1[length1-1]-'0';//获取num1当前位的数字
		if(length2>0)//如果num2还没加完(注意,num2是位数较少的)
			b=num2[length2-1]-'0';//获取num2当前位的数字
		else
			b=0;//如果num2加完了,num2对应位上就没有数来加了
				//这时我没有break,因为虽然num2没有数字来加了,但可能还有进位需要加
		sum=a+b+flag;//num1与num2对应位上的数字相加,再加上进位位
		if(sum>=10){//如果加起来大于于10,那就需要进位了
			num1[length1-1]='0'+sum%10;//计算加完之后,当前位应该是多少
			flag=1;//把进位标记置1
		}else{
			num1[length1-1]='0'+sum;//计算加完之后,当前位应该是多少
			flag=0;//把进位标记置0
		}
		length1--;//向高位移动1位
		length2--;//向高位移动1位
	}
	//如果两个数对应位都加完了,进位位是1,说明位数要增加1了
	//比如99+1,加完之后,变成了三位数100,其实就是再在前面加一位1
	if(1==flag)
		num1="1"+num1;
	return num1;
}
int main()
{
	string num1;
	string num2;
	while(cin>>num1>>num2){
		cout<<"num1:"<<num1<<endl;
		cout<<"num2:"<<num2<<endl;
		cout<<"sum:"<<plus(num1,num2)<<endl;
	}
	return 0;
}

       下图为运行截图:



展开阅读全文

没有更多推荐了,返回首页