高精度运算——大数相加、大数相减、大数相乘、大数相除

大数相加

#include <bits/stdc++.h>

using namespace std;

vector<int> getAdd(vector<int>& A,vector<int>& B)//保证函数中在前面的数组长度大
{
    
    
    if(A.size()<B.size()) return getAdd(B,A); //保证函数中在前面的数组长度大
    vector<int> C;
    int cf=0;
    for (int i=0;i<A.size();++i){
    
    
        cf+=A[i];
        if(i<B.size()) cf+=B[i]; //不取等号
        C.push_back(cf%10);
        cf/=10;
    }
    if (cf) C.push_back(1);
    return C;
}

int main()
{
    
    
    string a,b;
    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');//倒序存储,数组低位存数值低位
    auto C=getAdd(A,B);  //cpp中的auto类型,自动匹配C的类型
    for (int i=C.size()-1;i>=0;i--) printf("%d",C[i]); //从高位开始输出
    
    return 0;
}

大数相减

#include <bits/stdc++.h>

using namespace std;

bool cmp(vector<int> & A,vector<int>& B) //判断A是不是小于B,如果是,返回true,大于等于返回false
{
    
    
    if(A.size()!=B.size()) return A.size()<B.size();//如果A.size()<B.size(),则返回的是true,交换位置
    for (int i = A.size()-1; i >= 0; --i) {
    
     //从高位开始往低位比较
        if (A[i]!=B[i])  return A[i]<B[i];
    }
    return false;//两数相等,也不需要交换位置,返回false即可
}

vector<int> getSub(vector<int> & A,vector<int>& B)
{
    
       //求A-B的绝对值
    if (cmp(A,B))  return getSub(B,A);
    vector<int> C;
    int cf=0;
    for (int i = 0; i < A.size(); ++i) {
    
    
        cf=A[i]-cf;   //确保A和B的值不变,存于cf中
        if (i<B.size()) cf-=B[i];
        C.push_back((cf+10)%10);//不借位的情况下,cf=A[i]-B[i]-cf后的取值范围:[-10,9],e.g.  1000000-999999
        if (cf<0) cf=1; //两个数相减,最多向前借1位,就像两个数相加,最多往前进1位
        else cf=0;                    //不进位的情况下,两个数相加,A[i]+B[i]+cf,取值:[0,19]
    }
    while (C.size()>1 && C.back()==0) C.pop_back();
    return C;
}

int main() {
    
    
    string a,b;
    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');
    auto C=getSub(A,B);   //求得A-B的绝对值
    if (cmp(A,B))  cout<<"-";
    for (int i=C.size()-1;i>=0;--i) cout<<C[i];

    return 0;
}

大数乘小数

#include <bits/stdc++.h>

using namespace std;

vector<int> getMul(vector<int>& A,int b)
{
    
    
    vector<int> C;
    int t=0;//进位
    for (int i = 0; i < A.size(); ++i) {
    
    
        t+=A[i]*b;
        C.push_back(t%10);
        t/=10;
    }
    if (t)  C.push_back(t); //不管最后的进位有几位,都可以直接当做最高位。
    while (C.size() > 1 && C.back() == 0) C.pop_back();  //考虑结果为0的特例,就留一个0

    return C;
}

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

    return 0;
}

大数除以小数

#include <bits/stdc++.h>

using namespace std;

vector<int> getDiv(vector<int> &A,int b,int &r)
{
    
    
    vector<int> 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());//倒置一下,高高低低存储,方便从高位开始处理操作,加位或者删除
    while (C.size()>1 && C.back()==0) C.pop_back();
    return C;
}

int main() {
    
    
    string a;
    vector<int> A;
    int b,r;//b是除数,r是余数
    cin>>a>>b;
    for (int i = a.size()-1; i >= 0; --i) A.push_back(a[i]-'0');//数的低位在数组低处
    auto C=getDiv(A,b,r);
    for (int i = C.size()-1; i >= 0; --i) cout<<C[i];
    cout<<endl<<r<<endl;

    return 0;
}

事实上,除法不同于其它三种运算,可以先从高位开始运算,不需要先把数值低位转换到数组低位处运算

所以可以按下面的方式,对应转换即可:数值高位在最前面,数组低位。

但为了和前面的运算保持统一,还是按照高高低低存储方法,即上面的方法。

#include <bits/stdc++.h>

using namespace std;

int main()
{
    
    
    string a;
    vector<int> A,C;
    int b,r=0; //b是除数,r是余数
    cin>>a>>b;
    for (int i = 0; i < a.size(); ++i)  A.push_back(a[i]-'0');
    //除法操作,只有除法特殊,可以先从高位运算,所以这里不用变换
    for (int i = 0; i < A.size(); ++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();
    for (int i = C.size()-1; i >= 0; --i) cout<<C[i];
    cout<<endl<<r;

    return 0;
}

大数乘大数

两个数都是大数时,相乘,核心公式: C[i+j]+=A[i]*B[j];

#include <bits/stdc++.h>

using namespace std;

vector<int> getMul(vector<int> &A,vector<int> &B)
{
    
    
    int len=A.size()+B.size(); //m位数×n位数,最多m+n位,最少m+n-1位,两位数中:99*100=9900,两位数相乘肯定小于9900
    vector<int> C(len); //0到len-1下标的值都被初始化为0
    for (int i = 0; i < A.size(); ++i)
        for (int j = 0; j < B.size(); ++j)  C[i+j]+=A[i]*B[j];
    int cf=0;
    for (int i = 0; i < C.size(); ++i) {
    
    //按最大位数来算,最后一步的进位也算在内了
        cf+=C[i];
        C[i]=cf%10;
        cf/=10;
    }
    while (C.size()>1 &&C.back()==0) C.pop_back();
    return C;
}

int main() {
    
    
    string a,b;
    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');
    auto C=getMul(A,B);
    for (int i = C.size()-1; i >= 0; --i)  cout<<C[i];//从高位开始输出

    return 0;
}

猜你喜欢

转载自blog.csdn.net/HangHug_L/article/details/112975974