高精度加减乘除

高精度<vector方法>

加法

//高精度
/*vector容器中常见的成员函数
size()返回实际元素个数
clear()移出所有的元素,容器大小变为0
empty()判断容器中是否有元素,若无元素,返回true,反之返回false
front()返回第一个元素的引用 
back()返回最后一个元素的引用 
push_back()在序列的尾部添加一个元素 
pop_back()移出序列尾部的元素
swap()交换两个容器的所有元素*/ 
#include<iostream>
#include<vector>//一般用vector来装大整数,因为其自带size函数,来表示数组的长度,就不用再开一个额外的变量来存储

using namespace std;

vector<int> add(vector<int> &A,vector<int> &B)
{
    int t = 0;//进位定义为t 
    vector<int> C;
    for(int i = 0;i < A.size()||i < B.size(); i ++ )//小于更大的那个数组的长度 
	{
        if( i < A.size() ) t += A[i];
        if( i < B.size() ) t += B[i];
        C.push_back(t % 10);//若t大于10的话,只能保留其的个位 
        t /= 10;
    }
    if(t) C.push_back(1);//如果最高位还有进位,则还要再补充一个1到最高位 
    return C;
}

int main()
{
	string a,b;//因为太长了,所以用字符串形式string来存进来 
	vector<int>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<int>C = add(A,B);
	
	for(int i=C.size()-1;i>=0;i--)
	printf("%d",C[i]);
} 

减法

//除法
/*思路:
A-B:若A>=B 计算A-B;若A<B 计算-(B-A)
Ai-Bi-t:若>=0,则计算Ai-Bi-t
		若<0,则计算Ai-Bi+10-t 
*/ 
#include<iostream>
#include<vector>

using namespace std;
//比较大小if(cmp(A,B)) -> sub(A,B)  else -> sub(B,A)  + cout<<'-';
bool cmp(vector<int> &A,vector<int> &B){
    if(A.size() != B.size()) return A.size() > B.size();//若位数不同,则判断二者的位数大小,return true or false
    for(int i = A.size() - 1 ;i >= 0;i --){
        if(A[i] != B[i]) return A[i] > B[i];
    }//若位数相等,则从高位开始比较,由于是反着存的,所以高位是最后一位 
    return true;//若所有都相等,则直接返回true,因为大于和等于都可以用a-b 
}
//做减法
vector<int> sub(vector<int> &A,vector<int> &B){
    vector<int> C;
    for(int i = 0,t = 0;i < A.size();i ++)//因为A一定大于B,所以可直接小于A.size() 
	{ 
        t = A[i] - t;
        if(i < B.size())t -= B[i];//判断B是否有这一位,当有这一位的时候才需考虑将其减去 
        C.push_back((t + 10) % 10);//即可保证t大小于0两种情况合二为一 
        if(t < 0) t = 1;//借位 
        else t = 0;
    }
    while(C.size() > 1&&C.back() == 0) C.pop_back();//应要大于1,因为若只有一位且其为0的时候不可以将其抹掉,应保留。其余的将前导零抹去 
    return C;
}
int main()
{
	string a,b;//因为太长了,所以用字符串形式string来存进来 
	vector<int>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');
	if(cmp(A,B))
	{
		vector<int>C = sub(A,B);
		for(int i=C.size()-1;i>=0;i--)
			printf("%d",C[i]);
	}
	else
	{
		vector<int>C = sub(B,A);
		printf("-");
		for(int i=C.size()-1;i>=0;i--)
			printf("%d",C[i]);
	}
} 

乘法

#include<iostream>
#include<vector>

using namespace std;

vector<int> mul(vector<int> &A,int b){
    int t = 0;
    vector<int> C;
    for(int i = 0;i < A.size(); i ++)
	{
        t += A[i] * b;//将进位的数直接加上大数该位的值乘以小数 
        C.push_back(t % 10);//C该位的值等于t的最后一位 
        t /= 10;
    }
    if(t > 0) C.push_back(t);
    while(C.size() > 1 && C.back() == 0) C.pop_back();
    return C;
}
int main()
{
	string a;//大数用字符串读进来 
	int b;//小数直接读 
	cin>>a>>b;
	vector<int>A;
	for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0');
	
	vector<int>C=mul(A,b);
	
	for(int i=C.size()-1;i>=0;i--) printf("%d",C[i]);
	
	return 0;
 } 

除法

//高精除以低精
/* 思路:将被除数从第一位开始除以除数,得到的值放在对应结果位上,余数乘以10加上下一位被除数 */
#include<iostream>
#include<vector>
#include<algorithm> 
using namespace std;
//A/b,商是C,余数是r 
vector<int> div(vector<int> &A,int b ,int &r){
    r = 0;
    vector<int> C;
    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());
    while(C.size() > 1 && C.back() == 0) C.pop_back();
    return C;
}

int main()
{
	string a;//大数用字符串读进来 
	int b;//小数直接读 
	cin>>a>>b;
	vector<int>A;
	for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0');
	
	int r;//定义一个r为余数 
	vector<int>C=div(A,b,r);
	
	for(int i=C.size()-1;i>=0;i--) printf("%d",C[i]);
	cout<<endl<<r<<endl;//先输出商再输出回车和余数 
	return 0;
 } 
//涵盖高精除以高精以及高精除以低精
#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

bool cmp(vector<int> &A,vector<int> &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;
}//该函数用于判断A和B数的大小,当A>=B时,返回true,否则返回false 

vector<int> sub(vector<int> &A,vector<int> &B){
    vector<int> C;
    for(int i = 0,t = 0; i < A.size();i ++){
        t  = A[i] - t;
        if(i < B.size()) t -= B[i];
        C.push_back((t + 10) % 10);
        if(t < 0) t = 1;
        else t = 0;
    }
    while(C.size() > 1 && C.back() == 0) C.pop_back();
    return C;
}//减法函数 

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 ++){
        if(i < A.size()) t += A[i];
        if(i < B.size()) t += B[i];
        C.push_back(t % 10);
        t /= 10;
    }
    if(t) C.push_back(t);
    return C;
}//相加函数 

void mul(vector<int> &temp,int len){
        reverse(temp.begin(),temp.end());
        for(int i = 0;i < len ;i ++) temp.push_back(0);
        reverse(temp.begin(),temp.end());
}//位数每多1位,则在temp中多加一个0 

void result_add(vector<int> &result,int len){
    vector<int> temp;//定义一个temp容器 
    temp.push_back(1);//先放一个1进去 
    mul(temp,len);//len为位数差
    result = add(result,temp);
}//用于乘以10的n次方 

int main(){
    string a,b;
    cin>>a>>b;
    vector<int> A,B,result,one;
    one.push_back(1);
    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');
    if(!cmp(A,B)){
        cout<<"0";
        return 0;
    }
    while(cmp(A,B)){
        //位数差
        int len = A.size() - B.size();
        if(len <= 1){
            while(cmp(A,B)){
                result = add(result,one);//就相当于result++,但由于高精度数加1也应该用高精度来解决,所以只能再开一个vector来存1
                A = sub(A,B);
            }
        }else{
            vector<int> temp = B;
            mul(temp,len - 1);//将B的值放到temp里面,防止B的值发生改变,又因为A与B的位数差大,所以在B后面加零再进行运算 
            A = sub(A,temp);
            result_add(result,len - 1);//在B后加了几个零,在结果时就要加几个零 
        }
    }
    for(int i = result.size() - 1 ;i >= 0;i --) cout<<result[i];
    return 0;
}
该代码源自Xuuxxi
posted @ 2021-04-09 20:48  小滢小滢考第一名  阅读(74)  评论(0编辑  收藏  举报