高精度——加减乘除

一、高精度加法

1、思路

高精度加法一般都是由于所需要加的数字位数过大,如1e6位,想要实现,我们需要开数组来存储每一位,然后依次对每一位相加,同时进行进位,具体看代码展示

逆序输入是为了方便进位

2、代码

#include<iostream>
#include<vector>
using namespace std;
const int N=1e6+10;
vector<int> add(vector<int> &A,vector<int> &B)
{
	vector<int> C;
	int t=0;//用来计算每一位加完后的数字 
	for(int i=0;i<A.size()||i<B.size();i++)//当A,B中较长的所有位遍历完再结束, 
	{
		if(i<A.size())//当这一位上A有数字时,t加上这个数 
			t+=A[i];
		if(i<B.size())//当这一位上B有数字时,t加上这个数 
			t+=B[i];
		C.push_back(t%10);//将所得结果的各位输到C中 
		t/=10;//t保留进位数字给下一位加上 
	}
	if(t)//最后的一位要是仍有进位,就在最后加个1 
		C.push_back(1);
	return C;
}
int main()
{
	string a,b
	vector<int> A,B,C;
	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');
	C=add(A,B);
	for(int i=C.size()-1;i>=0;i--)
		printf("%d",C[i]);	
	return 0;
}

二、高精度减法

1、思路

与加法相差不多,需要注意2点

1、我们需要先判断被减数和减数的大小,让绝对值大的减绝对值小的

2、我们用t当前位的数,同时也表示是否借位,每次遍历到新的一位时,都先减去t,然后用t+A[i]-B[i],存当前位计算完的值。

(t+10)%10,当不需要借位时,计算完t肯定是个大于等于0的个位数,%10取的是个位数,所以+10不影响。当需要借位时,t肯定是个负数,借位+10后就是所得结果

2、代码

#include<iostream>
#include<vector>

using namespace std;
bool cmp(vector<int> &A,vector<int> &B)//判断两个数字谁大谁小
{
    if(A.size()!=B.size())//如果A,B位数不同 
        return A.size()>B.size();//判断A的位数是否大于B的位数 
    for(int i=A.size();i>=0;i--)//位数一样,将每一位依次比较
        if(A[i]!=B[i])//如果这一位两个数不同 
            return A[i]>B[i];//判断这一位是否有A>B 
    return 1;//A=B是也返回true
}
vector<int> sub(vector<int> &A,vector<int> &B)
{
    vector<int> C;
    int t=0,al=A.size(),bl=B.size();//t记录当前位计算的数,并且判断是否有借位
    for(int i=0;i<al;i++)
    {
        t=A[i]-t;//先减去借位
        if(i<bl)//当前位数小于B的位数
            t-=B[i];//减去当前位的B
        C.push_back((t+10)%10);//当不需要借位时,计算完t肯定是个大于等于0的个位数,%10取的是个位数,所以+10不影响。
//当需要借位时,t肯定是个负数,借位+10后就是所得结果
        if(t<0)     t=1;//当t为负数时代表要借位 
        else        t=0;
    }
    while(C.size()>1&&C.back()==0)//去掉前导0
        C.pop_back();
    return C;
}
string s1,s2;
vector<int> A,B,C;
int main()
{
    cin>>s1>>s2;
    for(int i=s1.size()-1;i>=0;i--)
        A.push_back(s1[i]-'0');
    for(int i=s2.size()-1;i>=0;i--)
        B.push_back(s2[i]-'0');
    if(cmp(A,B))//当A大于B时(绝对值)
        C=sub(A,B);
    else
    {
        C=sub(B,A);
        cout<<"-";
    }
    for(int i=C.size()-1;i>=0;i--)
        cout<<C[i];
    return 0;
}

三、高精度乘法——大数*小数情况

1、思路

我们将较小的乘数看成一个整体(int类型),然后去乘较大的数(string类型)

2、代码

#include<iostream>
#include<vector>
using namespace std;
vector<int> mul(vector<int> &A,int b)
{
    vector<int> C;
    int t=0,al=A.size();
    for(int i=0;i<al||t;i++)//当没有遍历完A的时候或者到最后进位没有进完时
    {
        if(i<al)
            t+=A[i]*b;
        C.push_back(t%10);
        t/=10;
    }
    while(C.size()>1&&C.back()==0)//去除前导0,刚开始不知道哪来的前导0,wa了一次才知道,当有个乘数为0时乘积就是一堆0
        C.pop_back();
    return C;
}
string s;
int b;
vector<int> A,C;
int main()
{
    cin>>s>>b;
    for(int i=s.size()-1;i>=0;i--)
        A.push_back(s[i]-'0');
    C=mul(A,b);
    for(int i=C.size()-1;i>=0;i--)
        cout<<C[i];
    return 0;
}

四、高精度除法

1、思路

2、代码

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> div(vector<int> &A,int b,int &r)//b是除数,r是余数 
{
	vector<int> C;
	r=0;//刚开始余数为0 
	for(int i=A.size()-1;i>=0;i--)
	{
		r=r*10+A[i];//上一位的余数*10加上这一位数 
		C.push_back(r/b);//将商向下取整记录 
		r%=b;//记录余数 
	} 
	reverse(C.begin(),C.end());//由于是逆序输入的,用reverse反转过来 
	while(C.size()>1&&C.back()==0)//去除前导0 
		C.pop_back();
	return C;
}
int main()
{
	string a;
	int b;
	cin>>a>>b;
	vector<int> A,C;
	for(int i=a.size()-1;i>=0;i--)
		A.push_back(a[i]-'0');
	int r;
	C=div(A,b,r);
	for(int i=C.size()-1;i>=0;i--)
		printf("%d",C[i]);
	cout<<endl<<r<<endl;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值