高精度板子

前言:写一写自己高精度易错的地方,内容并不适合初学者,还有高精除高精的锅蒟蒻补不上了.


I.高精加法

记住进位数x的定义,并记得最后x!=0时将x加上.

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define e exit(0)
#define R register
char s[510],t[510];
int x,id,lena,lenb,a[510],b[510],c[510];
int main()
{
//    freopen("s.in","r",stdin);
//    freopen("s.out","w",stdout);
    scanf("%s",s),scanf("%s",t);
    lena=strlen(s),lenb=strlen(t);
    for(R int i=0;i<lena;++i)
        a[i]=s[lena-i-1]-'0';
    for(R int j=0;j<lenb;++j)
        b[j]=t[lenb-j-1]-'0';
    while(id<lena||id<lenb)
    {    
        c[id]=a[id]+b[id]+x;
        x=c[id]/10;
        c[id]%=10;
        ++id;
    }
    --id;
    if(x!=0)
        c[++id]=x;
    for(R int j=id;j>=0;--j)
        printf("%d",c[j]);
    return 0;
}

II.高精减法

①理解借位x的定义,每次做减法时要考虑是否要借位,并在这之后将x变为1或0.

②注意被减数比减数大的情况,要在运算之前将次交换.

③清前导零时,要特判"0-0"的特殊情况.

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define e exit(0)
#define R register
char a[10010],b[10010];
int x,id,lena,lenb,lens,lent,s[10010],t[10010],c[10010];
bool check()
{
    if(lena<lenb)
        return true;
    else if(lena>lenb)
        return false;
    else if(lena==lenb)
    {    
        for(R int i=0;i<lena;++i)
            if(a[i]<b[i])
                return true;
        return false;
    }
}
void chang()
{
    printf("-");
    char c[10010];
    for(R int i=0;i<lena;++i)
        c[i]=a[i];
    for(R int i=0;i<lenb;++i)
        a[i]=b[i];
    for(R int i=0;i<lena;++i)
        b[i]=c[i];
    swap(lena,lenb);
}
int main()
{
//    freopen("s.in","r",stdin);
//    freopen("s.out","w",stdout);
    scanf("%s",a),scanf("%s",b);
    lena=strlen(a),lenb=strlen(b);
    if(check()) chang();
    lens=lena,lent=lenb;
    for(R int i=0;i<lens;++i)
        s[i]=a[lena-i-1]-'0';
    for(R int i=0;i<lent;++i)
        t[i]=b[lenb-i-1]-'0';
    while(id<lena||id<lenb){
        if(s[id]-t[id]-x<0){
            c[id]=s[id]+10-t[id]-x;
            x=1;
        }
        else if(s[id]-t[id]-x>=0){
            c[id]=s[id]-t[id]-x;
            x=0;
        }
        ++id;
    }
    --id;
    while(c[id]==0&&id>=0)
        --id;
    if(id==-1)
    {
        cout<<0;
        return 0;
    }
    for(R int i=id;i>=0;--i)
        cout<<c[i];
    return 0;
}

III.高精乘

①建议字符串的id从1开始.

②特判" 0*0 "的情况.

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#define R register
char s[2010],t[2010];
int a[2010],b[2010],c[5010],lena,lenb,lenc,x;
int main()
{
//    freopen("s.in","r",stdin);
//    freopen("s.out","w",stdout);
    scanf("%s",s+1),scanf("%s",t+1);
    lena=strlen(s+1),lenb=strlen(t+1);
    if((lena==1&&s[1]=='0')||(lenb==1&&t[1]=='0'))
    {
        printf("0");
        return 0;
    }
    for(R int i=1;i<=lena;++i)
        a[i]=s[lena-i+1]-'0';
    for(R int i=1;i<=lenb;++i)
        b[i]=t[lenb-i+1]-'0';
    for(R int i=1;i<=lena;++i)
    {
        x=0;
        for(R int j=1;j<=lenb;++j)
        {
            c[i+j-1]=a[i]*b[j]+c[i+j-1]+x;
            x=c[i+j-1]/10;
            c[i+j-1]%=10;
        }
        c[lenb+i]=x;
    }
    lenc=lena+lenb;
    while(c[lenc]==0)
        --lenc;
    for(R int i=lenc;i>=1;--i)
        printf("%d",c[i]);
    return 0;
}

IV.高精除低精

够除就除,不够除就存,注意前导0.

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define R register
#define ll long long
char s[5010];
long long a[5010],c[5010],lena,last,deep,b,sur;
int main()
{
//    freopen("s.in","r",stdin);
//    freopen("s.out","w",stdout);
    scanf("%s",s+1),scanf("%lld",&b);
    lena=strlen(s+1);
    for(R ll i=1;i<=lena;++i)
        a[i]=s[i]-'0';
    for(R ll i=1;i<=lena;++i){
        last=last*10+a[i];
        if(last<b&&sur==1){c[++deep]=0;}
        else if(last>=b){
            c[++deep]=last/b;
            last%=b;
            sur=1;
        }
    }
    for(R int i=1;i<=deep;++i)
        printf("%lld",c[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/xqysckt/p/11253857.html