1.大整數的存儲
用數組,高位存高位,低位存低位。注意,因爲是用字符串讀入數字,所以賦值給數組是,要反轉一下。爲了獲得大整數的長度,一般用一個數組,長度的結構體來保存。
struct bignum{
int d[1000];
int len;
bignum(){ //構造函數,爲結構體賦值
memset(d,0,sizeof(d));
len=0;
}
};
2大整數的四則運算----模擬
1)高精度加法
將該位上的兩個數字與進位相加,得到的結果取個位數作爲該位的結果,取十位數作爲新的進位
bignum add(bignum a,bignum b){
bignum c;
int carry=0; //進位
for(int i=0;i<a.len||i<b.len;i++){ //以較長的爲界
int temp=a.d[i]+b.d[i]+carry;
c.d[c.len++]=temp%10;
carry=temp/10;
}
if(carry!=0) //判斷最後進位
c.d[c.len++]=carry;
return c;
}
如果有一個是負數,則用高精度減法;如果兩個都是負的,則絕對值進行加法,最後加負號;
2)高精度減法
對某一步,比較被減位和減位,如果不夠減,則令被減位的高位減1,被減位加10再取減;如果夠減,則直接減。最後要注意減法後可能有多餘的前置0,要除去它們,同時也要保存結果至少有一位。
bignum sub(bignum a,bignum b){
bignum c;
for(int i=0;i<a.len||i<b.len;i++){
if(a.d[i]<b.d[i]){
a.d[i+1]--;
a.d[i]+=10;
}
c.d[i]=a.d[i]-b.d[i];
}
while(c.len-1>=1&&c.d[c.len-1]==0) //除去前置0,並保留一位
c.len--;
return c;
}
3)高精度與低精度的乘法
取bignum的某位與int型整體相乘,再與進位相加,所得結果的個位數作爲該位的結果,高位部分作爲新的進位
bignum multi(bignum a,int b){
bignum c;
int carry;
for(int i=0;i<a.len;i++){
int temp=a.d[i]*b+carry;
c.d[c.len++]=temp%10;
carry=temp/10;
}
while(carry!=0){ //乘法進位可能不止一位
c.d[c.len]=carry%10;
carry/=10;
}
return c;
}
如果a,b ,中存在負數,先記錄負號個數,在絕對值想乘;
4)高精度與低精度的除法
上一步的餘數乘以10加上該步的位,得到該步臨時的被除數,將其與除數比較:如果不夠除,則該位商位0;如果夠除,則商即爲對應的商,餘數即爲對應的餘數。同樣要注意前置0的問題;
bign div(bignum a,int b,int &r){
bign c;
c.len=a.len; //被除數的每一位和商都是對應的
for(int i=a.len-1;i>=0;i--){
r=r*10+a.d[i];
if(r<b) c.d[i]=0;
else{
c.d[i]=r/b;
r=r%b;
}
}
while(c.len-1>=1&&c.d[c.len-1]==0){
c.len--;
}
return c;
}
這裏,引用了一個r,可以在主函數裏面輸出最後的餘數