【C++】详解高精度加法、高精度减法、高精度乘法、高精度除法代码

目录

1、引入

2、入门思路

3、数的存储

4、高精度加法

5、高精度减法

6、高精度乘法

7、高精度除法


1、引入

        在进行大整数运算中,因为在C++/C中整数最大也就是unsigned long long也就才(1e19+8e18)位,如果要几百位的相加减就不行了,所以就要用高精度了,这里只在C++/C上使用有价值,在例如python、Java语言上无需写此算法,python可以无限大,Java里有相关库可以引入。

2、入门思路

        我们如何制作一个算法,让其可以在C++/C中可以进行理论上无限位数的数进行运算,我们试想可以把数存储在数组中,然后根据我们手算的思路,操作数组来进行运算,如下图所示:

【C++】详解高精度加法、高精度减法、高精度乘法、高精度除法代码_第1张图片

3、数的存储

        这里数的存储呢需要进行逆序存储,因为逆序存储方面进位。以加法为例所示:

 


【C++】详解高精度加法、高精度减法、高精度乘法、高精度除法代码_第2张图片


4、高精度加法

                我们通过手算的规律可以知道,因为随时可能存在例如(9+1)这的进位,则需要设置一个变量存储是否有进位。如果有进位。那么在下一次运算的时候就加上它,所以可以归结为

t=A[i]+B[i]+t;t初始化为0。

        我们算出t之后,t可能>=10,这时候我们只需要个位,然后进1,所以C[i]=t%10;

        如果算出是否有进位呢?只需要用t/10判断,因为t<10的时候,t=0;

        算法如下:      

#include 
#include 
using namespace std;

vector add(vector &A,vector &B){
	if(A.size() C;
	for(int i=0;i A,B;
	cin >> a >> b;
	//存入数组	
	for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0');
	for(int i=b.size()-1;i>=0;i--)B.push_back(b[i]-'0');
	//计算
	vector C=add(A,B);
	//返回
	for(int i=C.size()-1;i>=0;i--){
	cout << C[i];
	}
	return 0; 
}

5、高精度减法

        这里不考虑-10-10等这些负数情况,只考虑正数

      高精度减法,我们要考虑到(进1)的情况,则也需要一个t来记录是否需要进1,与高精度加法思路相同,t=A[i]-B[i]-t;但是需要注意的是这里的t可能存在<0和>=0的情况,因为我们这里无法通过代码来通俗的描述进1变十的情况,那么就只能直接A[i]-t-B[i],那么必定会出现负数情况,那该如何存储到C数组中呢,只需要对(t+10)%10,存储即可,可以进行手算验证,这里的t+10呢是防止出现负数情况,如果是正数呢,t+10然后再模10其实就回去了,没有变。如t=3,13%10=3,如果是t=-2,存入的数就为8,这里因为借了十,就加10,也可以这样理解。

        那么这里t<0呢,就代表其实是需要进位的,所以就可以写t<0时,t=1;则会t=0;

        当然,这个后续需要去掉前导0,因为在运算时候可能位数改变如【C++】详解高精度加法、高精度减法、高精度乘法、高精度除法代码_第3张图片

        代码如下:

#include 
#include 
using namespace std;


bool cmp(vector &A,vector &B){//比较A和B谁大 
    if(A.size()!=B.size())return A.size()>B.size();
    for(int i=A.size()-1;i>=0;i--){
        if(A[i]!=B[i])return A[i]>B[i];
    }
    return true;
}

vector sub(vector &A,vector &B){
    if(!cmp(A,B))cout << '-';
    if(!cmp(A,B))return sub(B,A);//如果A不大于B,则转一下
    vector C;
    for(int i=0,t=0;i1 && C.back()==0)C.pop_back();
    return C;
}



int main(){
    string a,b;
    vector A,B;
    cin >> a >>b;
    for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0');
    for(int i=b.size()-1;i>=0;i--)B.push_back(b[i]-'0');
    vector C;
    C=sub(A,B);
    for(int i=C.size()-1;i>=0;i--){
        cout << C[i];
    }
    return 0;
    
}

6、高精度乘法

这里我们只考虑大数 X 小数的情况(A[i]xb),也就是b用int存储,在大多场合已经够用了

       在高精度乘法中,我们可以把乘数看做一个整体依次相乘被乘数,被除也需要用t标记进位,因为当相乘后需要进行逐次相加,则相加后,我们可以取除了余数的前几项的进位,然后用在下次计算中把t再次加起来。而计算结束的时候也就是没有进位的时候。        

        设C=(A[i]*b+t)%10;//运算后取模,这里需要把进位也加上去

        且t=(t+A[i]*b)/10;//运算后取除最后一项的前几项且加上进位并存储到t变量,为下一次做准备。

、例如:

【C++】详解高精度加法、高精度减法、高精度乘法、高精度除法代码_第4张图片

代码:

#include
#include 
using namespace std;


//C = A * b
vector mul(vector &A,int b){
	vector C;
	int t=0;//进位 
	for(int i=0;i1 && C.back()==0)C.pop_back();//当b是0时 可能出现多个0,这时候弹出 
	return C;
}


int main(){
	string 	a;
	int b;
	vector A;
	cin >> a >> b;
	for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0');
	vector C=mul(A,b);
	for(int i=C.size()-1;i>=0;i--)cout << C[i];
	return 0;
}
 

7、高精度除法

注意:除法区别于加法、减法、乘法,除法是从高位计算,这里也是用高精度x低精度

        因为除法比较特殊,没有所谓什么进位什么的,因为只会越来越小,除了需要处理前导0。这里只需要一个r变量存储计算过程中的余数就能轻松写出除法代码,因为计算机总是一个数字一个数字的进行扫描,第一位不能商的情况下会商一个0,每次求出r余数的时候,因为在数字没有扫描完全部的时候,都可以进行求商(包括0),程序执行时这样的,

        则r=r*10+A[i];

           c=r/b//将商存入商数组。

           r=r%b;//求每一步的余数

        例如:

【C++】详解高精度加法、高精度减法、高精度乘法、高精度除法代码_第5张图片

  代码:

#include
#include
#include
using namespace std;

vector div(vector &A,int &b,int &r){
	vector C;
	r=0;
	for(int i=A.size()-1;i>=0;i--){//高位开始,区别于加减乘 
		r=r*10+A[i];
		C.push_back(r/b);
		r%=b;
	}
	reverse(C.begin(),C.end());//注意:算出的结果也是正序的,这里翻转是因为需要去掉前导0.且与加减乘相对应; 
	while(C.size()>1 && C.back()==0 )C.pop_back();
	return C; 
}


int main(){
	string a;
	int b,r;
	vector A;
	cin >> a >> b;
	for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0');
	vector C=div(A,b,r);
	for(int i=C.size()-1;i>=0;i--)cout << C[i];
	cout << endl << r;
} 

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