大整數存儲數組
用一個字符串讀取輸入的大數,在轉換的時候,用反轉的方式存到一個int型的數組中。ide
struct bign{ int d[1000]; int len; bigh(){ memset(d,0,sizeof(d)); len=0; } }
bign change(string str){ bign a; a.len=str.size(); for(int i=0;i<a.len;i++){ a.d[i]=str[a.len-i-1]-'0'; } return a; }
大整數比較大小spa
先判斷二者的len大小,若是不鮮水果等,則以長的爲大;若是相等,則從高位到低位進行比較,知道出現某一位不等,就能夠判斷兩個數的大小。code
int compare(bign a,bign b){ if(a.len>b.len) return 1;//a大 else if(a.len<b.len) return -1;//b大 else{ for(int i=a.len-1;i>=0;i--){//從高位往低位比較 if(a.d[i]>b.d[i]) return 1;// 只要有一位a大,則a大 else if(a.d[i]<b.d[i]) return -1;//只要有一爲a小,則a小 } return 0;//兩數相等 } }
高精度加法blog
用豎式的形式進行計算,對其中一位進行加法的步驟,將該位上的兩個數字與進位相加,獲得的結果取個位數做爲該位的結果,取十位數做爲新的進位。字符串
bign add(bign a,bign b){string
bign c; int carry=0;//carry是進位 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; }
高精度減法class
保證a>b。不然,交換位置,減法後先輸出 「-」,再輸出結果‘。循環
對某一步,比較被減位和減位,若是不夠減,則令被減位的高位減一、被減位+10,再進行減法;若是夠減,則一直減。最後一步要注意減法後高位可能有多餘的0,要除去它們,但也要至少保證結果有一位數。di
bign sub(bign a,bign b){ bign c; for(int i=0;i<a.len||i<b.len;i++){ if(a.d[i]<b.d[i]){ a.d[i+1]--;//向高位借1 a.d[i]+=10; } c.d[c.len++]=a.d[i]-b.d[i];//減法結果爲當前位的結果 } while(c.len-1>=1&&c.d[c.len-1]==0){ c.len--;//去除高位的0,而且保證至少還有一位數。 } return c; } bign before_sub(bign a,bign b){ bign c; if(compare(a,b)==-1){//a比b小的話 c=sub(b,a); printf("-"); }else{ c=sub(a,b); } for(int i=c.len-1;i>=0;i--){ printf("%d",c.d[i]); } }
高精度與低精度的乘法
以147*35爲例,把147看做一個高精度bign類型,35看爲int類型。下面操做中,35始終爲一個總體。
一、7*35=245,取5做爲該位的結果,高位部分24做爲進位;
二、4*35=140,加上進位24,等於164,取個位4做爲該位的結果,高位16爲進位;
三、1*35=25,加上進位16,等於51,取1爲該位的結果,高位5爲進位。
四、沒得乘了,進位不爲0,把進位5直接做爲該位的結果。
bign multi(bign a,int b){ bign c; int carry=0; 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; }
高精度與低精度的除法
取上一步的餘數*10加上該步的位,獲得該步的被除數,將其與除數比較:
若是不夠除,則該位的商爲0;
若是夠除,則商爲對應的商,餘數即爲對應的餘數;
最後一步應注意,減法後 高位可能有多餘的0,要除去它們,但也保證結果至少有一位。
bign divide(bign a,int b,int& r){//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;//不夠除。商0; else{//夠除 c.d[i]=r/b; r=r%b; } } while(c.len-1>=1&&c.d[c.len-1]==0){ c.len--;//去除高位的0,但保證至少有一位數存在。 } return c; }