大整数计算器.docx

上传人:b****6 文档编号:7989012 上传时间:2023-01-27 格式:DOCX 页数:32 大小:75.26KB
下载 相关 举报
大整数计算器.docx_第1页
第1页 / 共32页
大整数计算器.docx_第2页
第2页 / 共32页
大整数计算器.docx_第3页
第3页 / 共32页
大整数计算器.docx_第4页
第4页 / 共32页
大整数计算器.docx_第5页
第5页 / 共32页
点击查看更多>>
下载资源
资源描述

大整数计算器.docx

《大整数计算器.docx》由会员分享,可在线阅读,更多相关《大整数计算器.docx(32页珍藏版)》请在冰豆网上搜索。

大整数计算器.docx

大整数计算器

目录

一.问题的概述、分析及研究意义;

二.流程图

三.算法设计

四.调试过程

五.源程序

一.问题的概述、分析及研究意义;

设计一个计算器实现两个任意长得整数的加、减、乘、除。

对数值很大,精度很高的数进行高精度大整数计算是一类十分常见的问题,但由于C语言中数据长度和范围受数据类型的限制,普通数学计算很难实现此问题,为尝试解决这个问题,专门设计一个C语言程序用于大整数的计算。

为了实现上述功能,采取双向循环链表表示长整数,每个结点含一个整型变量,仅绝对值不超过9999的整数,整个链表用十进制数表示。

利用头结点数据域的符号表示长整数的符号,相加过程不破坏两个操作数链表,对长整数位数不作上限。

为此需要两个结构数据类型:

双向循环链表和长整数。

本程序实现计算任意长的整数的四则运算.以用户和计算机对话的方式,即在计算机终端上显示“提示信息”之后,由用户在键盘上输入演示程序中规定的运算命令,然后程序就计算并显示出这两个数的运算。

本演示程序中,数字字符限定为[‘0’~‘9’]和字符‘,’,输入字符可以任意长,输入形式以“回车符”为结束标志,串中字符顺序不限,且允许出现重复字符。

利用双向循环链表现实长整数的存储,每个结点含一个整形变量。

输入的形式以回车结束,可以直接输入正数或负数,每四位一组,除数字和位于首位置的负号外,其它一切字符都将作为分隔符,连续多个分隔符当一个处理,但不使用分隔符也不影响结果。

二.流程图

 

三.算法设计

1.定义全局变量

#defineLENsizeof(structNode)

#defineMAX1000

#defineOK1

#defineERROR0

#defineOVERFLOW-1

#defineTRUE1

#defineFALSE0

typedefintStatus;

2,主要函数

(1)主程序模块:

//intmain()

(2)双向循环链表处理模块:

//Statusconversion(charstr[],NodeList&oprh);

//intcmplinklen(NodeListopr1,NodeListopr2);

//StatusCreat(NodeList&oprr,intlen);

//intcompare(NodeListopr1,NodeListopr2);

(3)长整数四则运算模块:

//Statusadd_bas(NodeListopr1,NodeListopr2,NodeList&oprr);

//Statussub_bas(NodeListopr1,NodeListopr2,NodeList&oprr);

//Statusimul(NodeListopr1,NodeListopr2,NodeList&oprr);

//Statusidiv(NodeListopr1,NodeListopr2,NodeList&quti,NodeList&remand);

(4)界面模块:

//voidtitle();

//voidwelcome();

3,编写函数

(1)函数:

Statusconversion(charstr[],NodeList&oprh)

功能:

将字符串形式的操作数转换成所需的类型

(2)函数:

Statusinput(NodeList&opr1,NodeList&opr2,charstr[])

功能:

输入需要的操作数

(3)函数:

Statusoutput(NodeListoprr,charstr[])

功能:

输出需要的操作数以及判断其正确性

(4)函数:

Statusinitbuf(charstr[])

功能:

为数据对象或变量赋初值

(5)函数:

intcmplinklen(NodeListopr1,NodeListopr2)

功能:

比较两个输入数的大小,长返回1,短返回-1,否则返回0

(6)函数:

intlength(NodeListoprr)

功能:

求出链表长度

(7)函数:

StatusCreat(NodeList&oprr,intlen)

功能:

生成一个指定链表

(8)函数:

intcompare(NodeListopr1,NodeListopr2)

功能:

比较两个数的绝对值的大小

(9)函数:

Statusadd_bas(NodeListopr1,NodeListopr2,NodeList&oprr)

功能:

实现两个数相加

(10)函数:

Statussub_bas(NodeListopr1,NodeListopr2,NodeList&oprr)

功能:

实现两个数的相减

(11)函数:

Statusimul(NodeListopr1,NodeListopr2,NodeList&oprr)

功能:

实现两个数的相乘

(12)函数:

Statusidiv(NodeListopr1,NodeListopr2,NodeList&quti,NodeList&remand)

功能:

实现两个数的除法

 

四.调试过程

运行平台:

MicrosoftVisualC++6.0

1,欢迎界面

2,选择操作

 

3,加法运算

 

4,减法运算

 

5,乘法运算

 

6,除法运算

8,结束运行

五.源程序

#include

#include

#include

#defineLENsizeof(structNode)

#defineMAX1000

#defineOK1

#defineERROR0

#defineOVERFLOW-1

#defineTRUE1

#defineFALSE0

typedefintStatus;//自定义一个变量

typedefstructNode

{

intdata;

structNode*prior,*next;

}Node,*NodeList;//定义双向循环链表结构体

//===============输入模块===============

//求指数函数值

intaxp(inta,intk)

{

intr=1;

if(k==0)

return1;

for(;k>0;k--)

r=r*a;

returnr;

}

//输入转换函数

Statusconversion(charstr[],NodeList&oprh)

{//将字符串形式的操作数转换成所需的类型

NodeListp;

inti,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||(str[0]!

='-'&&str[0]!

='+'))&&(str[i]>'9'||str[i]<'0'))

returnERROR;

if(str[0]=='0'&&str[1]!

='\0')

returnERROR;

if((str[0]=='-'||str[0]=='+')&&str[1]=='0')

returnERROR;

if(str[i]!

='-'&&str[i]!

='+')

{

buffer=buffer+(str[i]-'0')*axp(10,k);

k++;

if(k==4||str[i-1]=='-'||str[i-1]=='+'||i==0)

{//将新建结点插入到头结点之后

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(str[0]=='-')

oprh->data='-';

else

oprh->data='+';

returnOK;

}

//输入函数

Statusinput(NodeList&opr1,NodeList&opr2,charstr[])

{

intflag=OK,i,n=0,l;

charb[MAX];

printf("\n请输入第一个操作数:

\n");

scanf("%s",b);

getchar();

l=strlen(b);

for(i=0;i

if(b[i]!

=',')

str[n++]=b[i];

str[n]='\0';

flag=conversion(str,opr1);

while(!

flag)

{

printf("ERROR!

Inputagain:

\n");

scanf("%s",str);

getchar();

flag=conversion(str,opr1);

}

printf("\n请输入第二个操作数:

\n");

scanf("%s",b);

getchar();

n=0;

l=strlen(b);

for(i=0;i

if(b[i]!

=',')

str[n++]=b[i];

str[n]='\0';

flag=conversion(str,opr2);

while(!

flag)

{

printf("ERROR!

Inputagain:

\n");

scanf("%s",str);

getchar();

flag=conversion(str,opr2);

}

returnOK;

}

//==================输出模块======================

//输出函数

Statusoutput(NodeListoprr,charstr[])

{

Statusinitbuf(charstr[]);

NodeListp;

inti,j,num[4];

if(!

oprr)

returnERROR;

p=oprr;

i=j=0;

initbuf(str);

if(oprr->data=='-')

str[i++]='-';

p=p->next;

if(p->next==oprr&&p->data==0)//若要输出的数为0则执行

str[i++]='0';

else

while(p!

=oprr)

{

num[0]=p->data/1000;

num[1]=(p->data-num[0]*1000)/100;

num[2]=(p->data-num[0]*1000-num[1]*100)/10;

num[3]=p->data-num[0]*1000-num[1]*100-num[2]*10;

while(j<4)

{

if(num[j]!

=0||(str[0]=='-'&&str[1]!

='\0')||(str[0]!

='-'&&str[0]!

='\0'))

//此判断语句是为了避免输出诸如:

00123…的情况

str[i++]=num[j]+'0';

j++;

}

p=p->next;

j=0;

str[i++]=',';

}

if(str[--i]==',')

str[i]='\0';

printf("%s",str);

printf("\n");

returnOK;

}

//================预处理及杂项操作模块====================

//缓冲区部分初始化函数

Statusinitbuf(charstr[])

{

inti;

for(i=0;i<=10;i++)

str[i]='\0';

returnOK;

}

//比较链表长度函数

intcmplinklen(NodeListopr1,NodeListopr2)

{//opr1链比opr2链长则返回1,短则返回-1,否则返回0

NodeListp1,p2;

p1=opr1->prior;

p2=opr2->prior;

while(p1->prior!

=opr1&&p2->prior!

=opr2)

{

p1=p1->prior;

p2=p2->prior;

}

if(p1->prior!

=opr1)

return1;

if(p2->prior!

=opr2)

return-1;

return0;

}

//求链表长度

intlength(NodeListoprr)

{

intcount=0;

NodeListp=oprr->next;

while(p!

=oprr)

{

count++;

p=p->next;

}

returncount;

}

//生成指定长度链表

StatusCreat(NodeList&oprr,intlen)

{

NodeListp;

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;

oprr->prior=p;

returnOK;

}

//比较opr1、opr2绝对值的大小

intcompare(NodeListopr1,NodeListopr2)

{

NodeListp1,p2;

p1=opr1->next;

p2=opr2->next;

if(cmplinklen(opr1,opr2)==1)//opr1比较长

return1;

elseif(cmplinklen(opr1,opr2)==-1)//opr2比较长

return-1;

else

{

while(p1->data==p2->data&&p1->next!

=opr1)//注意p1->next!

=opr1这条件

{

p1=p1->next;

p2=p2->next;

}

if(p1->data>p2->data)

return1;

elseif(p1->datadata)

return-1;

else

return0;

}

}

//=====================加减法模块==========================

//加法基本操作

Statusadd_bas(NodeListopr1,NodeListopr2,NodeList&oprr)

{//本算法实现A,B相加的操作。

intCF,buffer;

NodeListp1,p2,p3;

oprr=(NodeList)malloc(LEN);

oprr->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->next;

oprr->next=p3;

p3->data=buffer%10000;//应该将buffer的第四位赋给p3->data

p1=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->next=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)malloc(LEN);

oprr->next->prior=p3;

p3->prior=oprr;

p3->next=oprr->next;

oprr->next=p3;

p3->data=CF;

}

oprr->data='+';

returnOK;

}

//减法基本操作

Statussub_bas(NodeListopr1,NodeListopr2,NodeList&oprr)

{//本算法实现A,B相减的操作。

//将A链分成与B链长相等的底位部分,和剩余的高位部分,并做相应处理。

intCF,buffer,flag;

NodeListp1,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;

}

else

{

buffer=p1->data-(p2->data+CF);

CF=0;

}

p3=(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

{

buffer=10000+p1->data-CF;

CF=1;

}

else

{

buffer=p1->data-CF;

CF=0;

}

p3=(NodeList)malloc(LEN);

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->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='+';

returnOK;

}

//---------------------带符号加法函数---------------------

Statusadd(NodeListopr1,NodeListopr2,NodeList&oprr)

{

if(opr1==NULL||opr2==NULL)

returnERROR;

if(opr1->data==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

sub_bas(opr2,opr1,oprr);

oprr->data='-';

}

else

{//A>=B的情况

sub_bas(opr1,opr2,oprr);

oprr->data='+';

}

}

else

{//(-A)+B的情况

if(compare(opr1,opr2)==1)

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1