大整數計算器_第1頁
大整數計算器_第2頁
大整數計算器_第3頁
大整數計算器_第4頁
大整數計算器_第5頁
已閱讀5頁,還剩23頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、 目錄一 問題的概述、分析及研究意義;二 流程圖 三 算法設計四 調試過程五 源程序 一問題的概述、分析及研究意義;設計一個計算器實現兩個任意長得整數的加、減、乘、除。對數值很大,精度很高的數進行高精度大整數計算是一類十分常見的問題,但由于C語言中數據長度和范圍受數據類型的限制,普通數學計算很難實現此問題,為嘗試解決這個問題,專門設計一個C語言程序用于大整數的計算。為了實現上述功能,采取雙向循環鏈表表示長整數,每個結點含一個整型變量,僅絕對值不超過9999的整數,整個鏈表用十進制數表示。利用頭結點數據域的符號表示長整數的符號,相加過程不破壞兩個操作數鏈表,對長整數位數不作上限。為此需要兩個結構

2、數據類型:雙向循環鏈表和長整數。本程序實現計算任意長的整數的四則運算. 以用戶和計算機對話的方式,即在計算機終端上顯示“提示信息”之后,由用戶在鍵盤上輸入演示程序中規定的運算命令,然后程序就計算并顯示出這兩個數的運算。本演示程序中,數字字符限定為09和字符,輸入字符可以任意長,輸入形式以“回車符”為結束標志,串中字符順序不限,且允許出現重復字符。利用雙向循環鏈表現實長整數的存儲,每個結點含一個整形變量。輸入的形式以回車結束,可以直接輸入正數或負數,每四位一組,除數字和位于首位置的負號外,其它一切字符都將作為分隔符,連續多個分隔符當一個處理,但不使用分隔符也不影響結果。二流程圖 歡迎界面選擇操作

3、加法運算減法運算乘法運算除法運算運行結果繼續結束是否 三算法設計1定義全局變量#define LEN sizeof(struct Node)#define MAX 1000#define OK 1#define ERROR 0#define OVERFLOW -1#define TRUE 1#define FALSE 0typedef int Status; 2,主要函數 (1)主程序模塊:/int main() (2)雙向循環鏈表處理模塊: /Status conversion(char str,NodeList &oprh); /int cmplinklen(NodeList op

4、r1,NodeList opr2); /Status Creat(NodeList &oprr,int len); /int compare(NodeList opr1,NodeList opr2); (3)長整數四則運算模塊: /Status add_bas(NodeList opr1,NodeList opr2,NodeList &oprr); /Status sub_bas(NodeList opr1,NodeList opr2,NodeList &oprr); /Status imul(NodeList opr1,NodeList opr2,NodeList &

5、amp;oprr); /Status idiv(NodeList opr1,NodeList opr2,NodeList &quti,NodeList &remand); (4)界面模塊: /void title(); /void welcome();3,編寫函數(1)函數:Status conversion(char str,NodeList &oprh)功能:將字符串形式的操作數轉換成所需的類型(2)函數:Status input(NodeList &opr1,NodeList &opr2,char str) 功能:輸入需要的操作數(3)函數:Sta

6、tus output(NodeList oprr,char str) 功能:輸出需要的操作數以及判斷其正確性(4)函數:Status initbuf(char str) 功能:為數據對象或變量賦初值(5)函數:int cmplinklen(NodeList opr1,NodeList opr2)功能:比較兩個輸入數的大小,長返回1,短返回-1,否則返回0(6)函數:int length(NodeList oprr) 功能:求出鏈表長度(7)函數:Status Creat(NodeList &oprr,int len) 功能:生成一個指定鏈表(8)函數:int compare(NodeL

7、ist opr1,NodeList opr2) 功能:比較兩個數的絕對值的大小(9)函數:Status add_bas(NodeList opr1,NodeList opr2,NodeList &oprr) 功能:實現兩個數相加(10)函數:Status sub_bas(NodeList opr1,NodeList opr2,NodeList &oprr) 功能:實現兩個數的相減(11)函數:Status imul(NodeList opr1,NodeList opr2,NodeList &oprr) 功能:實現兩個數的相乘(12)函數:Status idiv(Node

8、List opr1,NodeList opr2,NodeList &quti,NodeList &remand) 功能:實現兩個數的除法四調試過程運行平臺:Microsoft Visual C+ 6.01, 歡迎界面 2,選擇操作3,加法運算4,減法運算5, 乘法運算6, 除法運算8, 結束運行五源程序#include<string.h>#include<stdlib.h>#include<stdio.h>#define LEN sizeof(struct Node)#define MAX 1000#define OK 1#define ER

9、ROR 0#define OVERFLOW -1#define TRUE 1#define FALSE 0typedef int Status;/自定義一個變量typedef struct Nodeint data;struct Node *prior,*next;Node,*NodeList;/定義雙向循環鏈表結構體/=輸入模塊=/求指數函數值int axp(int a,int k)int r=1;if(k=0)return 1;for(;k>0;k-)r=r*a;return r;/輸入轉換函數Status conversion(char str,NodeList &oprh

10、)/將字符串形式的操作數轉換成所需的類型NodeList p;int i,k,buffer;k=buffer=0;oprh=(NodeList)malloc(LEN);oprh->next=oprh;oprh->prior=oprh;for(i=strlen(str)-1;i>=0;i-)/若輸入的數不合法就返回重新輸入if(i!=0 | (str0!='-' && str0!='+')&&(stri>'9' | stri<'0')return ERROR;if(str

11、0='0' && str1!='0')return ERROR;if(str0='-' | str0='+') && str1='0')return ERROR;if(stri!='-' && stri!='+') buffer=buffer+(stri-'0')*axp(10,k); k+; if(k=4 | stri-1='-' | stri-1='+' | i=0)/將新建結點插入到

12、頭結點之后 p=(NodeList)malloc(LEN); oprh->next->prior=p; p->prior=oprh; p->next=oprh->next; oprh->next=p; p->data=buffer; buffer=k=0;if(str0='-')oprh->data='-'elseoprh->data='+'return OK;/輸入函數Status input(NodeList &opr1,NodeList &opr2,char str)in

13、t flag=OK,i,n=0,l; char bMAX; printf("n請輸入第一個操作數:n");scanf("%s",b);getchar();l=strlen(b);for(i=0;i<l;i+)if(bi!=',')strn+=bi;strn='0'flag=conversion(str,opr1); while(!flag) printf("ERROR!Input again:n"); scanf("%s",str); getchar(); flag=conve

14、rsion(str,opr1);printf("n請輸入第二個操作數:n");scanf("%s",b);getchar();n=0;l=strlen(b);for(i=0;i<l;i+)if(bi!=',')strn+=bi;strn='0'flag=conversion(str,opr2); while(!flag) printf("ERROR!Input again:n"); scanf("%s",str);getchar(); flag=conversion(str,o

15、pr2);return OK;/=輸出模塊=/輸出函數Status output(NodeList oprr,char str)Status initbuf(char str);NodeList p;int i,j,num4;if(!oprr)return ERROR;p=oprr;i=j=0;initbuf(str);if(oprr->data='-')stri+='-'p=p->next;if(p->next=oprr && p->data=0)/若要輸出的數為0則執行stri+='0'else whi

16、le(p!=oprr) num0=p->data/1000; num1=(p->data-num0*1000)/100; num2=(p->data-num0*1000-num1*100)/10; num3=p->data-num0*1000-num1*100-num2*10; while(j<4) if(numj!=0 | (str0='-' && str1!='0')|(str0!='-' && str0!='0') /此判斷語句是為了避免輸出諸如:00123的情況

17、 stri+=numj+'0' j+; p=p->next; j=0; stri+=',' if(str-i=',') stri='0'printf("%s",str);printf("n");return OK;/=預處理及雜項操作模塊=/緩沖區部分初始化函數Status initbuf(char str)int i;for(i=0;i<=10;i+)stri='0'return OK;/比較鏈表長度函數int cmplinklen(NodeList opr1,

18、NodeList opr2)/opr1鏈比opr2鏈長則返回1,短則返回-1,否則返回0NodeList p1,p2;p1=opr1->prior;p2=opr2->prior;while(p1->prior!=opr1 && p2->prior!=opr2)p1=p1->prior;p2=p2->prior;if(p1->prior!=opr1)return 1;if(p2->prior!=opr2)return -1;return 0;/求鏈表長度int length(NodeList oprr)int count=0;Nod

19、eList p=oprr->next;while(p!=oprr)count+;p=p->next;return count;/生成指定長度鏈表Status Creat(NodeList &oprr,int len)NodeList p;oprr=(NodeList)malloc(LEN);p=oprr;while(len>0)p->next=(NodeList)malloc(LEN);p->next->data='?'p->next->prior=p;p=p->next;len-;p->next=oprr;o

20、prr->prior=p;return OK;/比較opr1、opr2絕對值的大小int compare(NodeList opr1,NodeList opr2)NodeList p1,p2;p1=opr1->next;p2=opr2->next;if(cmplinklen(opr1,opr2)=1)/opr1比較長return 1;else if(cmplinklen(opr1,opr2)=-1)/opr2比較長return -1;elsewhile(p1->data=p2->data && p1->next!=opr1)/注意p1->

21、;next!=opr1這條件 p1=p1->next; p2=p2->next;if(p1->data>p2->data)return 1;else if(p1->data<p2->data)return -1;else return 0;/=加減法模塊=/加法基本操作Status add_bas(NodeList opr1,NodeList opr2,NodeList &oprr)/本算法實現A,B相加的操作。int CF,buffer; NodeList p1,p2,p3;oprr=(NodeList)malloc(LEN); opr

22、r->next=oprr;oprr->prior=oprr;p1=opr1->prior;p2=opr2->prior;CF=buffer=0;while(p1!=opr1 && p2!=opr2)buffer=p1->data+p2->data+CF;CF=buffer/10000;/若buffer的值大于9999則產生進位,賦給CF /將新建結點插入到頭結點之后 p3=(NodeList)malloc(LEN); oprr->next->prior=p3; p3->prior=oprr;p3->next=oprr-

23、>next;oprr->next=p3;p3->data=buffer%10000;/應該將buffer的第四位賦給p3->datap1=p1->prior;p2=p2->prior;while(p1!=opr1)/處理opr1鏈的剩余部分buffer=p1->data+CF;CF=buffer/10000;p3=(NodeList)malloc(LEN);/將新建結點插入到頭結點之后 oprr->next->prior=p3; p3->prior=oprr;p3->next=oprr->next;oprr->nex

24、t=p3;p3->data=buffer%10000;p1=p1->prior;while(p2!=opr2)/處理opr2鏈的剩余部分buffer=p2->data+CF;CF=buffer/10000;p3=(NodeList)malloc(LEN);/將新建結點插入到頭結點之后 oprr->next->prior=p3; p3->prior=oprr;p3->next=oprr->next;oprr->next=p3;p3->data=buffer%10000;p2=p2->prior;if(CF)p3=(NodeList

25、)malloc(LEN); oprr->next->prior=p3; p3->prior=oprr;p3->next=oprr->next;oprr->next=p3;p3->data=CF;oprr->data='+'return OK;/減法基本操作Status sub_bas(NodeList opr1,NodeList opr2,NodeList &oprr)/本算法實現A,B相減的操作。/將A鏈分成與B鏈長相等的底位部分,和剩余的高位部分,并做相應處理。int CF,buffer,flag;NodeList p

26、1,p2,p3,qh,qt,qq;oprr=(NodeList)malloc(LEN); oprr->next=oprr;oprr->prior=oprr;p1=opr1->prior;p2=opr2->prior;CF=buffer=flag=0;while(p2!=opr2)/opr2鏈的長度小于等于opr1鏈的if(p1->data<(p2->data+CF)buffer=10000+p1->data-(p2->data+CF);CF=1;elsebuffer=p1->data-(p2->data+CF);CF=0;p3=

27、(NodeList)malloc(LEN); oprr->next->prior=p3; p3->prior=oprr;p3->next=oprr->next;oprr->next=p3; p3->data=buffer;p1=p1->prior;p2=p2->prior;while(p1!=opr1)/處理opr1鏈剩下的部分if(p1->data<CF)buffer=10000+p1->data-CF;CF=1;elsebuffer=p1->data-CF;CF=0;p3=(NodeList)malloc(LEN

28、); oprr->next->prior=p3; p3->prior=oprr;p3->next=oprr->next;oprr->next=p3; p3->data=buffer;p1=p1->prior;/處理鏈表開頭結點值為0的無意義情況,若鏈表本身表示0,則不做如下處理 p3=oprr->next;while(p3->data=0 && p3->next!=oprr)p3=p3->next;flag=1;if(flag)qh=oprr->next;/保存無用結點的頭尾指針 qt=p3->

29、prior;/為釋放做準備 oprr->next=p3;/重接next鏈 p3->prior=oprr;/重接prior鏈qt->next=NULL; while(qh!=NULL)/重接prior鏈 qq=qh; qh=qh->next; free(qq);oprr->data='+'return OK;/-帶符號加法函數-Status add(NodeList opr1,NodeList opr2,NodeList &oprr)if(opr1=NULL | opr2=NULL)return ERROR;if(opr1->data=

30、opr2->data)/opr1,opr2符號相同add_bas(opr1,opr2,oprr);if(opr1->data='+')/opr1與opr2均為正數,即A+B的形式(A,B均是正數,下同)oprr->data='+'else/opr1與opr2均為負數,即(-A)+(-B)的形式oprr->data='-'else/符號不相同if(opr1->data='+')/A+(-B)的情況if(compare(opr1,opr2)=-1)/A<B的情況sub_bas(opr2,opr1,o

31、prr);oprr->data='-'else/A>=B的情況sub_bas(opr1,opr2,oprr);oprr->data='+'else/(-A)+B的情況if(compare(opr1,opr2)=1)/A>B的情況sub_bas(opr1,opr2,oprr);oprr->data='-'else/A<=B的情況sub_bas(opr2,opr1,oprr);oprr->data='+'return OK;/-帶符號減法函數-Status sub(NodeList opr1,

32、NodeList opr2,NodeList &oprr)if(opr1=NULL | opr2=NULL)return ERROR;if(opr1->data=opr2->data)/opr1,opr2符號相同if(opr1->data='+')/A-B的情況if(compare(opr1,opr2)=-1)/A<B的情況sub_bas(opr2,opr1,oprr);oprr->data='-'else/A>=B的情況sub_bas(opr1,opr2,oprr);oprr->data='+'

33、else/(-A)-(-B)的情況if(compare(opr1,opr2)=1)/A>B的情況sub_bas(opr1,opr2,oprr);oprr->data='-'else/A<B的情況sub_bas(opr2,opr1,oprr);oprr->data='+'else/opr1,opr2符號不同add_bas(opr1,opr2,oprr);if(opr1->data='+')oprr->data='+'elseoprr->data='-'return OK;/=

34、乘法模塊=/乘法函數Status imul(NodeList opr1,NodeList opr2,NodeList &oprr)NodeList ph1,ph2,pt1,pt2,p3,pt3,qh,qt,qq;int len,CF,flag;long buffer;if(compare(opr1,opr2)=-1)/若opr1比opr2小則被乘數跟乘數調換ph1=opr2;pt1=ph1->prior;ph2=opr1;pt2=ph2->prior;elseph1=opr1;pt1=ph1->prior;ph2=opr2;pt2=ph2->prior;len=

35、length(opr1)+length(opr2);Creat(oprr,len);qq=oprr->next;while(qq!=oprr)qq->data=0;qq=qq->next;buffer=CF=0;p3=oprr->prior;while(pt2!=ph2)pt1=ph1->prior;pt3=p3;while(pt1!=ph1)buffer=pt1->data*pt2->data+pt3->data+CF;CF=(int)buffer/10000;pt3->data=(int)buffer%10000;pt1=pt1->

36、;prior;pt3=pt3->prior;pt3->data=CF;CF=0;pt2=pt2->prior;p3=p3->prior;/處理鏈表開頭結點值為0的無意義情況,若鏈表本身表示0,則不做如下處理flag=0; p3=oprr->next;while(p3->data=0 && p3->next!=oprr)p3=p3->next;flag=1;if(flag)qh=oprr->next;/保存無用結點的頭尾指針 qt=p3->prior;/為釋放做準備 oprr->next=p3;/重接next鏈 p

37、3->prior=oprr;/重接prior鏈qt->next=NULL; while(qh!=NULL)/釋放無用結點 qq=qh; qh=qh->next; free(qq);if(opr1->data=opr2->data | oprr->next->data=0)oprr->data='+'elseoprr->data='-'return OK;/=除法模塊=/除法子函數int idiv_sub(NodeList &opr1,NodeList opr2)NodeList p1,p2,qh,qt

38、,qq;int count,CF,buffer,flag;count=0;while(compare(opr1,opr2)!=-1)CF=buffer=0;p1=opr1->prior; p2=opr2->prior;while(p2!=opr2) if(p1->data<(p2->data+CF) buffer=10000+p1->data-(p2->data+CF); CF=1; else buffer=p1->data-(p2->data+CF); CF=0; p1->data=buffer;p1=p1->prior;p2

39、=p2->prior; if(p1!=opr1)/處理opr1鏈剩下的部份buffer=p1->data-CF;p1->data=buffer;/清頭0flag=0; p1=opr1->next; while(p1->data=0 && p1->next!=opr1) p1=p1->next; flag=1; if(flag) qh=opr1->next;/保存無用結點的頭尾指針 qt=p1->prior;/為釋放做準備 opr1->next=p1;/重接next鏈 p1->prior=opr1;/重接prior

40、鏈 qt->next=NULL; while(qh!=NULL)/釋放無用結點 qq=qh; qh=qh->next; free(qq);count+;return count;/除法函數Status idiv(NodeList opr1,NodeList opr2,NodeList &quti,NodeList &remand)/quti為商數鏈,remand為余數鏈int len_quti,len_reman,buffer;NodeList q1,q2,pq;if(compare(opr1,opr2)=-1)/除數比被除數大Creat(quti,1);quti-

41、>next->data=0;quti->next->next=quti;quti->prior=quti->next;remand=opr1;elselen_quti=length(opr1)-length(opr2); len_reman=length(opr2); Creat(quti,len_quti+1);/開辟商數鏈 Creat(remand,len_reman);/開辟余數鏈q1=opr1->next;q2=remand->next;/初始化remand鏈while(q2!=remand)q2->data=q1->data

42、;q1=q1->next;q2=q2->next;pq=quti->next;q1=q1->prior;/指針退回一步while(q1!=opr1)buffer=idiv_sub(remand,opr2);pq->data=buffer;if(q1->next!=opr1)remand->prior->next=(NodeList)malloc(LEN);remand->prior->next->next=remand;remand->prior->next->prior=remand->prior;re

43、mand->prior=remand->prior->next;remand->prior->data=q1->next->data;if(remand->next->data=0 && remand->next->next!=remand)remand->next->next->prior=remand;remand->next=remand->next->next;q1=q1->next;pq=pq->next;pq=quti->prior;while(p

44、q->data='?')pq=pq->prior;pq->next=quti;quti->prior=pq;if(opr1->data='-' && remand->next->data!=0)remand->data='-'elseremand->data='+'if(opr1->data=opr2->data | quti->next->data=0)quti->data='+'elsequti->data

45、='-'return OK;/=主操作模塊=void title()int i;printf("n");for(i=0;i<33;i+)printf("*");printf("大整數計算器");for(i=0;i<33;i+)printf("*");printf("n");printf(" 輸入1、2、3、4選擇操作: n");printf(" 1、加法 n");printf(" 2、減法 n");printf(" 3、乘法 n");printf(" 4、除法 n"); printf("= =n");printf(" 請選擇:");/打印歡迎屏幕void welcome()printf("=nn"); printf("歡迎使用大整數計算器n

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論