版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、.C 語言中超大整數(shù)乘法運(yùn)算在計(jì)算機(jī)中,長整型 (long int) 變量的范圍是 -2147483648 至 2147483647 ,因此若用長整型變量做乘法運(yùn)算,乘積最多不能超過 10 位數(shù)。即便用雙精度型 (double) 變量,也僅能保證 16 位有效數(shù)字的精度。在某些需要更高精度的乘法運(yùn)算的場合,需要用別的辦法來實(shí)現(xiàn)乘法運(yùn)算。比較容易想到的是做多位數(shù)乘法時(shí)列豎式進(jìn)行計(jì)算的方法,只要寫出模擬這一過程的程序,就能實(shí)現(xiàn)任意大整數(shù)的乘法運(yùn)算。經(jīng)過查閱資料,找到一種更易于編程的方法,即“列表法”。下面先介紹“列表法”:例如當(dāng)計(jì)算 8765 x 234時(shí),把乘數(shù)與被乘數(shù)照如下列出,見表1 :把表
2、 1 中的數(shù)按圖示斜線分組(橫縱坐標(biāo)和相等的數(shù)分為一組),把每組數(shù)的累加起來所得的和記在表格下方,見表 2 :從最低位的 20 開始,保留個(gè)位數(shù)字“0 ”,把個(gè)位以外的數(shù)“2 ”進(jìn)到前一位;把39次低位的加上低位進(jìn)上來的2 得 41 ,保留個(gè)位數(shù)字“1 ”,把“4 ”進(jìn)到前一位;以此類推,直至最高位的 16 ,16 加上低位進(jìn)上來的4 得 20 ,保留“0 ”,把2 進(jìn)到最高位,得乘積答數(shù)2051010 。根據(jù)以上思路就可以編寫C 程序了,再經(jīng)分析可得:.1、一個(gè) m 位的整數(shù)與一個(gè)n 位的整數(shù)相乘,乘積為m+n-1位或 m+n 位。2、程序中,用三個(gè)字符數(shù)組分別存儲乘數(shù)、被乘數(shù)與乘積。由第1
3、 點(diǎn)分析知,存放乘積的字符數(shù)組的長度應(yīng)不小于存放乘數(shù)與被乘數(shù)的兩個(gè)數(shù)組的長度之和。3、可以把第二步“計(jì)算填表”與第三四步“累加進(jìn)位”放在一起完成,可以節(jié)省存儲表格2 所需的空間。4、程序關(guān)鍵部分是兩層循環(huán),內(nèi)層循環(huán)累計(jì)一組數(shù)的和,外層循環(huán)處理保留的數(shù)字與進(jìn)位。編寫的程序如下:#define MAXLENGTH 1000#include #include void compute(char *a, char *b, char *c);void main(void)char aMAXLENGTH, bMAXLENGTH, cMAXLENGTH * 2;puts(Input multiplier :
4、);gets(a);puts(Input multiplicand :);gets(b);compute(a, b, c);puts(Answer :);puts(c);getchar();.void compute(char *a, char *b, char *c)int i, j, m, n;long sum, carry;m = strlen(a) - 1;n = strlen(b) - 1;for (i = m; i = 0; i-)ai -= 0;for (i = n; i = 0; i-)bi -= 0;cm + n + 2 = 0;carry = 0;for (i = m +
5、n; i = 0; i-) /* i為坐標(biāo)和 */sum = carry;if (j = i - m) 0)j = 0;for ( ; j=i & j=n; j+) /* j為縱坐標(biāo) */sum += ai-j * bj; /*累計(jì)一組數(shù)的和*/ci + 1 = sum % 10 + 0; /*算出保留的數(shù)字*/carry = sum / 10; /*算出進(jìn)位 */if (c0 = carry+0) = 0) /* if no carry, */c0 = 040; /* c0 equals to space */.效率分析:用以上算法計(jì)算 m 位整數(shù)乘以 n 位整數(shù),需要先進(jìn)行 m x n 次
6、乘法運(yùn)算,再進(jìn)行約 m + n 次加法運(yùn)算和 m + n 次取模運(yùn)算 (實(shí)為整數(shù)除法 )。把這個(gè)程序稍加修改,讓它自己產(chǎn)生乘數(shù)與被乘數(shù),然后計(jì)算隨機(jī)的 7200 位整數(shù)互乘,在 Cyrix 6x86 pr166 機(jī)器的純 DOS 方式下耗時(shí) 7 秒(用 Borland C3.1 編譯 )。經(jīng)過改進(jìn),此算法效率可以提高約9 倍。注意到以下事實(shí): 8216547 x 96785 將兩數(shù)從個(gè)位起,每 3 位分為節(jié),列出乘法表,將斜線間的數(shù)字相加;8 216 54796 785將表中最后一行進(jìn)行如下處理:從個(gè)位數(shù)開始,每一個(gè)方格里只保留三位數(shù)字,超出1000 的部分進(jìn)位到前一個(gè)方格里;所以 82165
7、47 x 96785 = 795238501395也就是說我們在計(jì)算生成這個(gè)二維表時(shí),不必一位一位地乘,而可以三位三位地乘;在累加時(shí)也是滿 1000 進(jìn)位。這樣,我們在計(jì)算m 位整數(shù)乘以 n 位整數(shù),只需要進(jìn)行m x n / 9次乘法運(yùn)算,再進(jìn)行約 (m + n) / 3次加法運(yùn)算和 (m + n) /3次取模運(yùn)算??傮w看來,效率約是前一種算法的 9 倍。有人可能會(huì)想:既然能夠三位三位地乘,為什么不4 位 4 位甚至 5 位 5 位地乘呢?那不是可以.提高 16 乃至 25 倍效率嗎?聽我解來:本算法在累加表中斜線間的數(shù)字時(shí),如果用無符號長整數(shù) (范圍 0 至 4294967295) 作為累加
8、變量,在最不利的情況下 (兩個(gè)乘數(shù)的所有數(shù)字均是9) ,能夠累加約 4294967295/(999*999)=4300次,也就是能夠準(zhǔn)確計(jì)算任意兩個(gè)均不超過12900( 每次累加的結(jié)果 值 三位,故 4300*3=12900)位的整數(shù)相乘。如果4 位 4 位地乘,在最不利的情況下,能夠累加約4294967295/(9999*9999)=43次,僅能夠確保任意兩個(gè)不超過172 位的整數(shù)相乘,沒有什么實(shí)用價(jià)值,更不要說5 位了。請看改進(jìn)后的算法的實(shí)例程序:該程序隨機(jī)產(chǎn)生兩個(gè) 72xx 位的整數(shù),把乘數(shù)與積保存在 result.txt 中。在 Borland C+ 3.1 中用BCC -3 -O2
9、-G -mh -Z -f287 -pr -T- dashu.cpp編譯生成的 exe 文件在 Cyrix 6x86 pr166的機(jī)器上運(yùn)行耗時(shí)0.82 秒。程序 2 清單:#include#include#include#include#include#define N 7200 /作 72xx 位的整數(shù)乘法int max(int,int,int);int initarray(int a);void write(int a,int l);FILE *fp;void main()int a5000=0,b5000=0,k10001=0; /聲明存放乘數(shù)、被乘數(shù)與積的數(shù)組clock_t start
10、, end; /聲明用于計(jì)時(shí)的變量unsigned long c,d,e; / 聲明作累加用的無符號長整數(shù)變量 int i,j,la,lb,ma,mi,p,q,t; / 聲明其它變量 randomize(); / 初始化隨機(jī)數(shù).la=initarray(a); /產(chǎn)生被乘數(shù),并返回其長度lb=initarray(b); /產(chǎn)生乘數(shù),并返回其長度if(lala)?lb:la;for (q=0;q=0;i-) /累加斜線間的數(shù), i 為橫縱坐標(biāo)之和c=d; /將前一位的進(jìn)位標(biāo)志存入累加變量cma=max(0,i-la+1,i-lb+1); /求累加的下限mi=(ila-1)?(la-1):i; /
11、求累加的上限for(j=ma;j999)c%=1000; /取 c 的末三位ki=c; /保存至表示乘積的數(shù)組ke=k0+1000*d; /求出乘積的最高位end = clock();/停止計(jì)時(shí)fp = fopen(result.txt, w+); /保存結(jié)果到 result.txtprintf(nThe elapsed time was: %3.4fn, (end - start) / CLK_TCK);/ 打印消耗的時(shí)間.fprintf(fp,%d,a0); /打印被乘數(shù)最高位write(a,la); /打印被乘數(shù)其他位fprintf(fp,%d,b0); /打印乘數(shù)最高位write(b,
12、lb); /打印乘數(shù)其他位fprintf(fp,%ld,e); /打印乘積最高位write(k,la+lb-1); /打印乘積其他位fclose(fp);max(int a,int b,int c)int d;d=(ab)?a:b;return (dc)?d:c;int initarray(int a)int q,p,i;q=N+random(100);if(q%3=0)p=q/3;elsep=q/3+1;for(i=0;ip;i+)ai=random(1000);if(q%3=0)a0=100+random(900);if(q%3=2).a0=10+random(90);if(q%3=1)a0=1+random(9);return p;void write(int a,int l)int i;char
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 廣播電視傳輸與全球氣候變化宣傳考核試卷
- 2025年湘教新版必修1歷史下冊月考試卷含答案
- 2025年統(tǒng)編版2024必修4語文上冊階段測試試卷含答案
- 2025年新科版九年級生物下冊階段測試試卷含答案
- 2025年人教新起點(diǎn)選擇性必修3化學(xué)上冊月考試卷含答案
- 2025年粵教版八年級歷史下冊階段測試試卷含答案
- 2025年人教版必修1歷史下冊階段測試試卷
- 2025版民間借貸合同樣本四種借款人信用評估標(biāo)準(zhǔn)4篇
- 技術(shù)申請合同(2篇)
- 2025年度數(shù)據(jù)中心機(jī)房建設(shè)承包商借款合同模板3篇
- GB/T 43650-2024野生動(dòng)物及其制品DNA物種鑒定技術(shù)規(guī)程
- 2024年南京鐵道職業(yè)技術(shù)學(xué)院高職單招(英語/數(shù)學(xué)/語文)筆試歷年參考題庫含答案解析
- 暴發(fā)性心肌炎查房
- 口腔醫(yī)學(xué)中的人工智能應(yīng)用培訓(xùn)課件
- 工程質(zhì)保金返還審批單
- 【可行性報(bào)告】2023年電動(dòng)自行車項(xiàng)目可行性研究分析報(bào)告
- 五月天歌詞全集
- 商品退換貨申請表模板
- 實(shí)習(xí)單位鑒定表(模板)
- 數(shù)字媒體應(yīng)用技術(shù)專業(yè)調(diào)研方案
- 2023年常州市新課結(jié)束考試九年級數(shù)學(xué)試卷(含答案)
評論
0/150
提交評論