大数运算(5)——大数除法(取模、取余)
有關于大數除法的運算可以大致分為兩種:一種是求商(取模),另一種是求余數(取余)。
有兩個大整數a和b,當a==b時,a/b==1,余數是0。(a!=0,b!=0)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?當a>b時,a/b>=1,余數需要通過計算求得。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?當a<b時,a/b=0,余數就是a。
而我們經常需要求的便是當a>b,這種情況我們該如何求商和余數呢?
其實基本的思想就是反復做減法,看看從被除數里最多能減去多少個除數,商就是多少。一個一個減顯然太慢,如何減得更快一些呢?
以28536 除以23 為例來看一下:開始商為0。
先減去23 的1000 倍,就是23000,發現夠減1 次,余下5536,于是商的值就增加1000;
然后用5536減去2300,發現夠減2 次,余下936,于是商的值增加200,即1200;
再用936 減去230,夠減4 次,余下16,于是商值增加40,即1240。
最后,發現余下的數比23小,即為余數,即28536 / 23 得1240余16。
這時,你會發現這其實就是咱們人工計算時相當于列的豎式。
另外,注意:我這里寫的是有關大數除以大數的除法,同樣適用于大數除以int類型范圍的數,當然,也可以另寫關于大數除以int的數。
這里寫的全部是大整數,不包括小數。
下面是C語言代碼實現:
#include<stdio.h> #include<string.h> char a[100],b[100];//用兩個字符串用來輸入兩個大數 int x[100],y[100],z[100],m[100];//被除數 除數 商 余數 int digit;//大數的位數 void sub(int x[],int y[],int len1,int len2)//大數減法 { int i; for(i=0;i<len1;i++) { if(x[i]<y[i]) { x[i]=x[i]+10-y[i]; x[i+1]--; } else x[i]=x[i]-y[i]; } for(i=len1-1;i>=0;i--)//判斷減法結束之后,被除數的位數 { if(x[i]) { digit=i+1; break; } } } int judge(int x[],int y[],int len1,int len2) { int i; if(len1<len2) return -1; if(len1==len2)//若兩個數位數相等 { for(i=len1-1;i>=0;i--) { if(x[i]==y[i])//對應位的數相等 continue; if(x[i]>y[i])//被除數 大于 除數,返回值為1 return 1; if(x[i]<y[i])//被除數 小于 除數,返回值為-1 return -1; } return 0;//被除數 等于 除數,返回值為0 } } int main() { int i,j=0,k=0,temp; int len1,len2,len;//len兩個大數位數的差值 while(~scanf("%s %s",a,b)) { len1=strlen(a);//被除數位數 len2=strlen(b);//除數位數 for(i=len1-1,j=0;i>=0;i--)//將字符串中各個元素倒序儲存在數組中 x[j++]=a[i]-'0'; for(i=len2-1,k=0;i>=0;i--) y[k++]=b[i]-'0'; if(len1<len2)//當被除數位數 小于 除數位數時 { printf("商是:0\n"); printf("余數是:"); puts(a); } else //當被除數位數 大于或者 除數位數時 { len=len1-len2;//兩個大數位數的差值 for(i=len1-1;i>=0;i--)//將除數后補零,使得兩個大數位數相同。被除數:4541543329 除數:98745,加零后:9874500000 { if(i>=len) y[i]=y[i-len]; else y[i]=0; } len2=len1;//將兩個大數數位相同 digit=len1; //將原被除數位數賦值給digit for(j=0;j<=len;j++) { z[len-j]=0; while(((temp=judge(x,y,len1,len2))>=0)&&digit>=k)//判斷兩個數之間的關系以及位數與除數原位數的關系 { sub(x,y,len1,len2); //大數減法函數 z[len-j]++;//儲存商的每一位 len1=digit;//重新修改被除數的長度 if(len1<len2&&y[len2-1]==0) len2=len1;//將len1長度賦給len2; } if(temp<0)//若被除數 小于 除數,除數減小一位。例如:被除數:4541543329 除數:(原)98745,(加零后)9874500000,后退一位后:0987450000 { for(i=1;i<len2;i++) y[i-1]=y[i]; y[i-1]=0; if(len1<len2) len2--; } } printf("商是:"); for(i=len;i>0;i--)//去掉前綴0 { if(z[i]) break; } for(;i>=0;i--) printf("%d",z[i]); printf("\n"); printf("余數是:"); for(i=len1;i>0;i--) { if(x[i]) break; } for(;i>=0;i--) printf("%d",x[i]); printf("\n"); } } return 0; }與50位技術專家面對面20年技術見證,附贈技術全景圖
總結
以上是生活随笔為你收集整理的大数运算(5)——大数除法(取模、取余)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 互联网晚报 | 4月12日 星期二 |
- 下一篇: 大数运算(6)——大数阶乘(求位数)