日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

大数除法(超长整数运算除法器)详解

發(fā)布時間:2023/12/20 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 大数除法(超长整数运算除法器)详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在大數(shù)運算中,比較難實現(xiàn)的應(yīng)該是高精度/高精度的除法器。

目錄

一、原理

二、具體代碼解析

三、超長整數(shù)運算


一、原理

1.大數(shù)存儲

????????先說說大數(shù)在C語言程序中是怎么存儲的。我們使用長度為N的int數(shù)組來存儲無符號超長整數(shù),其中數(shù)組每個元素存儲的值上限為M。如下:???????

#define M 10000 //M進(jìn)制,int數(shù)組每個元素取值上限 #define N 5 //數(shù)組長度 int x[N]={0};

?????????因為int類型最多表示10位有效數(shù)字(最大值為2147483648),當(dāng)兩個有效位數(shù)為5的int類型變量相乘時其結(jié)果可能溢出,為了便于乘法器的實現(xiàn)M取值最好小于10000?

????????舉個例子,當(dāng)我們要用x存儲一個無符號超長整數(shù)6543210435135314時,數(shù)組x的值是這樣的:x[0]=5314,x[1]=3513,x[2]=2104,x[3]=6543,x[4]=0。

2.除法算法

除法操作數(shù)的關(guān)系如下:

????????被除數(shù)/除數(shù)=商......余數(shù),其中被除數(shù)=商*除數(shù)+余數(shù)

首先除數(shù)不能為0;

當(dāng)被除數(shù)為0時,商為0;

當(dāng)被除數(shù)小于除數(shù)時,商為0,余數(shù)為被除數(shù);

當(dāng)被除數(shù)等于除數(shù)時,商為1,余數(shù)為0;

?……

1)日常生活中,我們是這樣算除法的:

?

2)但是在大數(shù)除法中,我們不能直接這么算。例如:對于1234 5678 9000 / 1 2345,計算機(jī)沒法直接計算1234 5678 / 1 2345的結(jié)果。

3)在計算機(jī)中,減法的實現(xiàn)要比除法簡單得多,因此我們考慮把除法轉(zhuǎn)變成減法來計算。例如:對于7894/32,我們有:

?

通過被除數(shù)不斷地減去除數(shù),我們得到了余數(shù)22,而除數(shù)被減的次數(shù)就是商246。?

4)現(xiàn)在我們已經(jīng)知道了如何在計算機(jī)中把除法轉(zhuǎn)變成減法來運算,但一個除數(shù)一個除數(shù)的減實在太慢了,那么有沒有更快的算法呢?答案是肯定的,我們可以通過移位來加快“減”的速度,例如:

?

?如圖,7894=32*2*100+32*4*10+32*6*1+22,一共減去了2*100+4*10+6*1=246個32,所以7894/32的商為246。


二、具體代碼解析

1.首先函數(shù)原型如下:

#define M 10000 //M進(jìn)制,int數(shù)組每個元素取值上限 #define N 5 //數(shù)組長度 int div2(int n1[],int n2[],int quotient[]); /* 大數(shù)除法:無符號高精度整數(shù)/無符號高精度整數(shù),n1為被除數(shù),n2為除數(shù),quotient為商。函數(shù)正確執(zhí)行時返回整數(shù)1 */

此外還涉及到這些函數(shù):?

int add(int num1[],int num2[],int sum[]); /* 大數(shù)加法 */ int sub(int num1[],int num2[],int difference[]); /* 大數(shù)減法 */ int mul(int num1[],int num2[],int product[]); /* 大數(shù)乘法 */ int div(int num1[],int num2,int quotient[]); /* 大數(shù)除法:無符號高精度整數(shù)/無符號低精度整數(shù),其中num2>0且num2<=M */ int cmp(int num1[],int num2[]); /* 大數(shù)比較,num1>num2時return1,小于時返回-1,等于時返回0 */

?2.異常值處理

????????因為我們這里存儲的是無符號超長整數(shù),參與運算的操作數(shù)也應(yīng)該是無符號,并且數(shù)組的每個元素應(yīng)該小于M。所以有:?

int div2(int n1[],int n2[],int quotient[]){ int i=0; int num1[N]={0},num2[N]={0};for(i=0;i<N;i++){ //異常值處理if(n1[i]<0||n2[i]<0||n1[i]>=M||n2[i]>=M){printf("div2():Operand are forbidden!\n");return -2;} //初始化:num1[i]=n1[i];num2[i]=n2[i];quotient[i]=0; } return 1;//運算正確 }

????????這里說明一下為什么函數(shù)不直接用n1、n2參與運算,這是因為這個函數(shù)div2傳遞的參數(shù)都是指針,而接下來的算法將會改變被除數(shù)的值。為防止函數(shù)結(jié)束后被除數(shù)的值被改變,所以新定義了和n1、n2值相等的兩個局部變量num1、num2。

3.特殊值處理

????????包含以下特殊情況的處理:?(1)首先除數(shù)不能為0;(2)當(dāng)被除數(shù)為0時,商為0;(3)當(dāng)被除數(shù)小于除數(shù)時,商為0;(4)當(dāng)被除數(shù)等于除數(shù)時,商為1。

/*----特殊值處理----*///檢查除數(shù)是否為0for(i=N-1;i>=0&&(num2[i]==0);i--);//從高位開始尋找num2首個不為0的下標(biāo)if(i<0){printf("除數(shù)不能為0\n");return -1;}//被除數(shù)小于除數(shù)if((flag=cmp(num1,num2))==-1){quotient[0]=0;return 1;}//被除數(shù)等于除數(shù)else if(flag==0){quotient[0]=1;return 1;} /*---特殊值處理end---*/

?//別忘了在前面聲明flag!

4.處理完上述特殊情況,剩下的就是被除數(shù)大于除數(shù)的情況了,從這里開始就是算法的核心部分。

????????首先,為了加快減的速度,我們要盡可能地把除數(shù)左移。因為M取值10000,num2[i]有效位數(shù)為4,我們先4位(十進(jìn)制位)4位(十進(jìn)制位)的左移,直到除數(shù)num2大于被除數(shù)num1時停止。接下來把除數(shù)1位(十進(jìn)制位)1位(十進(jìn)制位)地右移,直到num1>num2時停止。這時,被除數(shù)num1剛好大于除數(shù)num2。?

/*---計算除數(shù)最大移位---*/if(num2[N-1]>0)flag=0;//flag=0表示除數(shù)不能移位,因為最高位>0for(counts=0;counts<N&&(flag>0);){//num2左移4位:for(i=N-1;i>0;i--)num2[i]=num2[i-1];num2[0]=0;counts++;//左移次數(shù)+4,counts+1flag=cmp(num1,num2);}counts=counts*4;for(i=0;i<counts&&(cmp(num1,num2)<0);i++){if(div(num2,10,num2)!=1) return -1;//如果除數(shù)num2大于被除數(shù)num1,右移1位}counts=counts-i;//此時counts為除數(shù)左移位數(shù) /*--計算除數(shù)最大移位end--*/

//這里左移一個10進(jìn)制位是用高精度整數(shù)/低精度整數(shù)除法div實現(xiàn)的

//counts為num2左移位數(shù)(十進(jìn)制位),別忘了在前面聲明!

5.計算被除數(shù)減去除數(shù)的次數(shù)

for(;counts>=0;counts--){if(cmp(num1,num2)>=0){//除數(shù)num2左移counts位時,num1最多能減去num2的次數(shù)times:for(times=0;times<M&&(cmp(num1,num2)>=0);times++){sub(num1,num2,num1);}//除數(shù)num2左移counts位時,被除數(shù)最多能減去除數(shù)t=times*(10^counts)次:for(i=0;i<N;i++){t[i]=0;m[i]=0;}//初始化t、mt[0]=times;m[0]=10;for(i=0;i<counts;i++){if(mul(t,m,t)!=1)return -1;}//“減”的次數(shù):if(add(quotient,t,quotient)!=1) return -1;}if(div(num2,10,num2)!=1) return -1;//除數(shù)右移1位 }

?//別忘了在前面聲明times、t、m!

6.完整的div2函數(shù)定義如下:

#define M 10000 //M進(jìn)制,int數(shù)組每個元素取值上限 #define N 5 //數(shù)組長度 //函數(shù)聲明: int add(int num1[],int num2[],int sum[]); int cmp(int num1[],int num2[]); int sub(int num1[],int num2[],int difference[]); int mul(int num1[],int num2[],int product[]); int div(int num1[],int num2,int quotient[]); /* ===無符號超長整數(shù) 除法=== quotient=n1/n2 高精度整數(shù)/高精度整數(shù) */ int div2(int n1[],int n2[],int quotient[]){int i=0,flag=1,counts=0,times=0;int t[N]={0},m[N]={0},num1[N]={0},num2[N]={0};for(i=0;i<N;i++){//異常值處理if(n1[i]<0||n2[i]<0||n1[i]>=M||n2[i]>=M){printf("div2():Operand are forbidden!\n");return -2;}//初始化:num1[i]=n1[i];num2[i]=n2[i];quotient[i]=0;}/*----特殊值處理----*///檢查除數(shù)是否為0for(i=N-1;i>=0&&(num2[i]==0);i--);//從高位開始尋找num2首個不為0的下標(biāo)if(i<0){printf("除數(shù)不能為0\n");return -1;}//被除數(shù)小于除數(shù)if((flag=cmp(num1,num2))==-1){quotient[0]=0;return 1;}//被除數(shù)等于除數(shù)else if(flag==0){quotient[0]=1;return 1;}/*---特殊值處理end---*//*---計算除數(shù)最大移位---*/if(num2[N-1]>0)flag=0;//flag=0表示除數(shù)不能移位,因為最高位>0for(counts=0;counts<N&&(flag>0);){//num2左移4位:for(i=N-1;i>0;i--)num2[i]=num2[i-1];num2[0]=0;counts++;//左移次數(shù)+4,counts+1flag=cmp(num1,num2);}counts=counts*4;for(i=0;i<counts&&(cmp(num1,num2)<0);i++){if(div(num2,10,num2)!=1) return -1;//如果除數(shù)num2大于被除數(shù)num1,右移1位}counts=counts-i;//此時counts為除數(shù)左移位數(shù)/*--計算除數(shù)最大移位end--*/for(;counts>=0;counts--){if(cmp(num1,num2)>=0){//除數(shù)num2左移counts位時,num1最多能減去num2的次數(shù)times:for(times=0;times<M&&(cmp(num1,num2)>=0);times++){sub(num1,num2,num1);}//除數(shù)num2左移counts位時,被除數(shù)最多能減去除數(shù)t=times*(10^counts)次:for(i=0;i<N;i++){t[i]=0;m[i]=0;}//初始化t、mt[0]=times;m[0]=10;for(i=0;i<counts;i++){if(mul(t,m,t)!=1)return -1;}//“減”的次數(shù):if(add(quotient,t,quotient)!=1) return -1;}if(div(num2,10,num2)!=1) return -1;//除數(shù)右移1位}return 1;//運算正確 }

三、超長整數(shù)運算

? ? ? ? 如果需要大數(shù)運算的完整代碼(包括輸入輸出、加減乘除函數(shù)),可以參考我的另一篇文章:超長整數(shù)運算——從斐波那契數(shù)列說起?的<無符號超長整數(shù)運算>部分。

總結(jié)

以上是生活随笔為你收集整理的大数除法(超长整数运算除法器)详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧洲成人一区二区三区 | 中文字幕日韩欧美 | 亚洲天堂不卡 | 亚洲黄色片子 | 午夜性影院 | 国产又大又黄又爽 | 国产福利精品视频 | 国产乱码av | 好吊妞视频这里只有精品 | 久久久久久九九九九九 | 黄色片a| 怡红院国产 | 玩弄人妻少妇500系列视频 | 精品动漫av| 一级特黄色大片 | 宅男深夜视频 | 日韩高清不卡 | 日韩欧美中文字幕在线观看 | 涩漫天堂 | 欧美六区 | 国产大片在线观看 | 天天干人人干 | 亚洲精品乱码久久久久久麻豆不卡 | 极品人妻一区二区三区 | 天天做天天干 | 最新免费黄色网址 | 两女双腿交缠激烈磨豆腐 | 国产91沙发系列 | 福利视频在线播放 | 一女三黑人理论片在线 | 91精品色 | 欧美黑人xxxⅹ高潮交 | 日日干日日摸 | 操碰91 | 婷婷91| 国产一级一片 | av国产一区 | av一区在线观看 | 天干夜夜爽爽日日日日 | 欧美日韩中文一区 | 日韩在线免费观看视频 | 毛片毛片毛片毛片毛片毛片毛片 | 亚洲欧洲无码一区二区三区 | 久久综合久久鬼色 | 久艹伊人| 欧美大片黄色 | 成人必看www. | 亚洲污污视频 | 国产精品探花一区二区三区 | 在线免费一区二区 | 日本青青草| 黄色a一片| 公妇借种乱htp109cc | 久久人妻少妇嫩草av | 怡红院成人影院 | 日韩欧美一二区 | 色视频免费看 | 男女男网站 | 久久这里有精品视频 | 综合网av | 都市激情校园春色亚洲 | 日韩熟妇一区二区三区 | 涩涩视频在线播放 | 国产.com | 免费看国产曰批40分钟 | 欧美成人一区二区三区 | 国产日本精品 | 一卡二卡在线观看 | 亚洲日本视频 | 日本三级中文字幕 | 欧美性受xxxx黑人xyx | 国内视频一区 | 99久久久无码国产精品衣服 | 超碰中文字幕在线 | 亚洲欧美色视频 | 精品亚洲永久免费精品 | 操皮视频| 亚洲午夜久久久 | 在线成人亚洲 | 亚洲精品国产精品乱码在线观看 | 国产精品国语 | 视频区小说区图片区 | 天天爽天天插 | 国产一级不卡毛片 | 精品国产伦一区二区三区 | 中文字幕第10页 | 亚洲人成人 | 久久综合成人 | 色欲久久久天天天精品综合网 | 午夜激情福利视频 | 国产福利短视频 | 欧美黑人一级爽快片淫片高清 | 色网综合 | 91伊人网| 天堂免费在线视频 | 特黄特色特刺激免费播放 | 操到喷水| 黄色a级大片| 女女h百合无遮羞羞漫画软件 |