【總結】高精度計算(Arbitrary-precision arithmetic)的模板 CPP Language

參考: Mr. He的高精度算法講稿

高精度的存儲結構:

#define maxn 5005 
struct bign //高精度結構體 
{ 
    int len,z[maxn]; 
    bign() //構造函數,初始化高精度變量的值爲 0 
    { 
        len=1; //0是一位數 
        memset(z,0,sizeof(z)); //各位數字爲0; 
    } 
}; 
bign a,b; //定義了一個高精度變量 

實現高精度運算的 13 大函數列表如下:

1、bign fuzhi(char *s) //賦值運算:把一個數字字符串賦值給高精度變量

bign fuzhi(char *s) //把一個字符串賦值給高精度 
{
    bign a; 
    a.len=strlen(s); 
    for(int i=0;i<a.len;i++) 
        a.z[a.len-1-i]=s[i]-48; 
    while(a.len>1 && a.z[a.len-1]==0) 
        a.len--; //去掉高位0 
    return a;
} 

2、bign fuzhi(int num) //賦值運算:把一個整數賦給高精度變量

bign fuzhi(int num) //把一個整數賦值給高精度 
{ 
    char s[25]; 
    sprintf(s,"%d",num); 
    return fuzhi(s); 
} 

3、void bign_in(bign &a) //高精度輸入

void bign_in(bign &a) //注意:別名變量 
{ 
    scanf("%s",s); 
    a=fuzhi(s); //把子符串賦值給高精度變量 
} 

4、void bign_out(bign &a) //高精度輸出

void bign_out(bign a) 
{ 
    for(int i=a.len-1;i>=0;i--) 
        printf("%d",a.z[i]); 
    printf("\n"); 
}

5、bool xiaoyu(bign a,bign b) //比較運算:a < b爲true

bool xiaoyu(bign a,bign b) 
{ 
    if(a.len!=b.len) return a.len<b.len; 
    for(int i=a.len-1;i>=0;i--) 
        if(a.z[i]!=b.z[i]) return a.z[i]<b.z[i]; 
    return false; 
}

就利用這個函數,可以判斷其他關係:
  ◆a>b 的判斷:b 小於 a

if(xiaoyu(b,a)) ……

  ◆a<=b 的判斷:b 不小於 a

if(!xiaoyu(b,a)) ……

  ◆a>=b 的判斷:a 不小於 b

if(!xiaoyu(a,b)) ……

  ◆a==b 的判斷:a 大於等於 b 且 b 大於等於 a

if(!xiaoyu(a,b) && !xiaoyu(b,a)) ……

  ◆a!=b 的判斷:a 大於 b 或 b 大於 a

if(xiaoyu(a,b) || xiaoyu(b,a)) ……

6、bign jia(bign a,bign b) //加法運算:高精度加高精度:a+b

bign jia(bign a,bign b) //高精度加法 a+b 
{ 
    bign c; 
    c.len=max(a.len,b.len); //和的位數,max()在<algorithm>中 
    for(int i=0;i<c.len;i++) //逐位相加 
        c.z[i]=a.z[i]+b.z[i]; 

    for(int i=0;i<c.len;i++) //處理進位 
        if(c.z[i]>=10) 
        { 
            c.z[i+1]++; 
            c.z[i]=c.z[i]-10; 
        } 
    if(c.z[c.len]>0) c.len++; //如過最高位有進位,則和的位數增加 
        return c; 
}

7、bign jian(bign a,bign b) //減法運算:高精度減高精度:a-b

bign jian(bign a,bign b) //高精度減法 a-b 
{ 
    bign c; 
    c.len=max(a.len,b.len); //差的位數,max()函數在<algorithm>中 
    for(int i=0;i<c.len;i++) //逐位相減 
        c.z[i]=a.z[i]-b.z[i]; 

    for(int i=0;i<c.len;i++) //處理借位 
        if(c.z[i]<0) 
        { 
            c.z[i+1]--; 
            c.z[i]=c.z[i]+10; 
        } 
    while(c.len>1 && c.z[c.len-1]==0) c.len--; //去掉整數的前導 0 
    return c; 
}

8、bign cheng(bign a,int b) //乘法運算:高精度乘int:a*b

bign cheng(bign a,int b) 
{ 
    bign c; 
    c.len=a.len+11; 
    for(int i=0;i<a.len;i++) 
    c.z[i]=a.z[i]*b; 

    for(int i=0;i<c.len;i++) 
        if(c.z[i]>=10) 
        { 
            c.z[i+1]=c.z[i+1]+c.z[i]/10; 
            c.z[i]=c.z[i]%10; 
        } 
    while(c.len>1 && c.z[c.len-1]==0) c.len--; 
    return c; 
} 

9、bign cheng(bign a,bign b) //乘法運算:高精度乘高精度:a*b

bign cheng(bign a,bign b) //高精度乘法 a*b 
{ 
    bign c; 
    c.len=a.len+b.len; 
    for(int i=0;i<a.len;i++) //a的第i位乘以 b 的第j位,得到c的第 i+j 位 
    for(int j=0;j<b.len;j++) 
        c.z[i+j]=c.z[i+j]+a.z[i]*b.z[j]; //邊乘邊加 

    for(int i=0;i<c.len;i++) //處理進位 
        if(c.z[i]>=10) 
        { 
            c.z[i+1]=c.z[i+1]+c.z[i]/10; 
            c.z[i]=c.z[i]%10; 
        } 
    while(c.len>1 && c.z[c.len-1]==0) c.len--; 
    return c; 
}

10、bign chu(bign a,int b) //除法運算:高精度除以int:a/b

bign chu(bign a,int b) //高精度除整數
{ 
    bign c; 
    int d=0; 
    c.len=a.len; 

    for(int i=a.len-1;i>=0;i--) 
    { 
        d=d*10+a.z[i]; 
        c.z[i]=d/b; 
        d=d%b; 
    } 
    while(c.len>1 && c.z[c.len-1]==0) 
        c.len--; 
    return c; 
} 

11、bign chu(bign a,bign b) //除法運算:高精度除以高精度:a/b

bign chu(bign a,bign b) //高精度除法a/b 
{ 
    bign c,d,ten; 
    c.len=a.len; 
    ten=fuzhi(10); //高精度的10
    for(int i=a.len-1;i>=0;i--) 
    { 
        d=cheng(d,ten); 
        d.z[0]=a.z[i]; 
        while(!xiaoyu(d,b)) //d>=b 
        { 
            c.z[i]++; 
            d=jian(d,b); 
        } 
    } 
    while(c.len>1 && c.z[c.len-1]==0) 
        c.len--; 
    return c; 
}

12、int yu(bign a,int b) //取餘運算:高精度除以int 的餘數:a%b

int yu(bign a,int b) //高精度除int取餘 
{ 
    int d=0; 
    for(int i=a.len-1;i>=0;i--) 
    { 
        d=d*10+a.z[i]; 
        d=d%b; 
    } 
    return d; 
} 

13、bign yu(bign a,bign b) //取餘運算:高精度除以高精度的餘數:a%b

bign yu(bign a,bign b) //高精度取餘 a%b 
{ 
    bign d,ten; 
    ten=fuzhi(10); 

    for(int i=a.len-1;i>=0;i--) 
    { 
        d=cheng(d,ten); 
        d.z[0]=a.z[i]; 
        while(!xiaoyu(d,b)) 
        { 
            d=jian(d,b); 
        } 
    } 
    while(d.len>1 && d.z[d.len-1]==0) 
    d.len--; 
    return d; 
}
發佈了74 篇原創文章 · 獲贊 7 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章