參考: 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;
}