高精度加减乘除

(大数运算)long long类型一般占8个字节是C/C++中的精度最高的整数类型,其取值范围是: -9223372036854775808~+9223372036854775807。在很多场景中,整数范围超出了long long的最值,例如在非对称加密中密钥长度一般为1024bit,转换为十进制数将超过300位,因此不能直接用内置的整数类型来运算。请编写大数运算类型MyBigInteger,使其支持大数据的加法,减法,乘法的运算。(除法为选做功能,除法运算符合C/C++中的整数除法运算的规则,有20%的测试用例包含除法运算,)
【输入】
大整数n,n的位数<=200
大整数m,m的位数<=200
运算符(+,-,*, /)
【输出】n和m的运算结果
例如:
【输入】
56891237265
32156789215
-
【输出】
24734448050

 

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int maxn = 500 + 5 ;
string n,m;
char str;
int flag1=1,flag2=1,c=1;
int len_x=0,len_y=0;
int ans[maxn * 2],x[maxn],y[maxn];
void Addition(){//x+y
    reverse(x,x+len_x);
    reverse(y,y+len_y);
    int digit = max(len_x,len_y);
    for(int i=0;i<digit;i++)
    {
        ans[i]+=x[i]+y[i];
        if(ans[i]>=10) ans[i+1]++,ans[i]%=10;
    }
    if(ans[digit]) digit++;
    if(c==-1) cout<<'-'; 
    for(int i=digit-1;i>=0;i--)
        cout<<ans[i];
}
int judge(int p[],int q[],int len)
{
    for(int i=len-1;i>=0;i--)
    {
        if(p[i]>q[i]) return 1;//p>q
        if(p[i]<q[i]) return -1;//p<q
    }
    return 0;//p=q
}
void Subtraction(){//x-y
    int vis = 1;
    reverse(x,x+len_x);
    reverse(y,y+len_y);
    if(len_x<len_y||(len_x==len_y && judge(x,y,len_x)==-1))
    {
        swap(x,y);
        swap(len_x,len_y);
        vis=-1;
    }
    int digit = max(len_x,len_y);
    for(int i=0;i<digit;i++)
    {
        ans[i]+=x[i]-y[i];
        if(ans[i]<0) ans[i+1]--,ans[i]+=10;
    }
    if(!ans[digit-1]) digit--;
    if(vis==-1) cout<<'-';
    vis=0;
    int p=0;
    for(int i=digit-1;i>=0;i--)
    {
        if(ans[i]!=0) vis=1;
        if(vis) 
        {
            p=1;
            cout<<ans[i];
        }
    }
    if(!p) cout<<0;
}
void Multiplication(){//x*y
    if((len_x==1 && x[0]==0 ) ||(len_y==1 && y[0]==0) )
    {
        cout<<0;
        return ;
    }
    reverse(x,x+len_x);
    reverse(y,y+len_y);
    int digit = len_x + len_y - 1;
    for(int i=0;i<len_x;i++)
        for(int j=0;j<len_y;j++)
            ans[i+j]+=x[i]*y[j];
    for(int i=0;i<digit;i++)
        if(ans[i]>=10)
        {
            ans[i+1]+=ans[i]/10;
            ans[i]%=10;
        }
    if(ans[digit]) digit++;
    if(flag1*flag2==-1) cout<<"-";
    for(int i=digit-1;i>=0;i--)
        cout<<ans[i];
}
/*
void chu(){//x/y gaojing/danjing
    if(len_x==1 && x[0]==0 )
    {
        cout<<0;
        return ;
    }
    if(len_y==1 && y[0]==0 ) return ;
    long long b=0,rema;
    for(int i=0;i<len_y;i++)
    {
        b*=10;
        b+=y[i];
    }
    for(int i=0;i<len_x;i++)
    {
        rema=x[i]%b;
        ans[i]=x[i]/b;
        x[i+1]+=rema*10;
    }1
    int j=0;
    while(!ans[j]) j++;
    if(j>=len_x) 
    {
        cout<<0;
        return;
    }
    if(flag1*flag2==-1) cout<<"-";
    for(int i=j;i<len_x;i++) cout<<ans[i];
    if(j>=len_x) cout<<0;
}*/

int z[maxn],len_z;
int num_substr(int pos){
    for(int i=0;i<len_y;i++) z[i+pos]=y[i];
    len_z=len_y+pos;
}
void sub(){//x,z
    if(len_x==len_z && judge(x,z,len_x)==0)
    {
        len_x=0;
        return ;
    }
    if(len_x>len_z || (len_x==len_z && judge(x,z,len_x)==1)){
        for(int i=0;i<len_x;i++){
            if(x[i]<z[i]){
                x[i+1]--;
                x[i]+=10;
            }
            x[i]-=z[i];
        }
        while(len_x>0 && !x[len_x-1]) len_x--;
        return;
    }
}
void Division(){//x/y gaojing/gaojing
    if(len_x==1 && x[0]==0 || len_x<len_y)
        {
            cout<<0;
            return ;
        }
    if(len_y==1 && y[0]==0 ) return ;
    reverse(x,x+len_x);
    reverse(y,y+len_y);
    int digit = len_x - len_y + 1;//shang
    for(int i=digit-1;i>=0;i--){
        memset(z,0,sizeof(z));
        num_substr(i);//y,z
        while(len_x>len_z || (len_x==len_z && judge(x,z,len_x)>=0)){
            ans[i]++;
            sub();//x,z
        }
    }
    while(digit && !ans[digit-1]) digit--;
    if(!digit) 
    {
        cout<<0;
        return ;
    }
    if(flag1*flag2==-1) cout<<"-";
    for(int i=digit-1;i>=0;i--) cout<<ans[i];
}
void Init()
{
    len_x=n.length();len_y=m.length();
    if(n[0]=='-') {
        n=n.substr(1,--len_x);
         flag1*=-1;
    }
     if(m[0]=='-') {
         m=m.substr(1,--len_y);
         flag2*=-1;
    }
    for(int i=0;i<len_x;i++) x[i]=n[i]-'0';
    for(int i=0;i<len_y;i++) y[i]=m[i]-'0';
}
int main()
{
     cin>>n>>m>>str;
     Init();
     if(str=='+' || str=='-'){
         if(str=='-') flag2*=-1;
         if(flag1==1 && flag2==1) Addition();
         if(flag1==1 && flag2==-1) Subtraction();
         if(flag1==-1 && flag2==1){
             swap(x,y);
             swap(len_x,len_y);
             Subtraction();
        }
        if(flag1==-1 && flag2==-1){
            c=-1;Addition();
        }
     }
     if(str=='*') Multiplication();
     if(str=='/') Division();
    return 0;
}

 

posted @ 2022-04-12 21:42  寒方  阅读(55)  评论(0编辑  收藏  举报