长整数运算说明书汇编.docx
- 文档编号:25583777
- 上传时间:2023-06-09
- 格式:DOCX
- 页数:35
- 大小:157.84KB
长整数运算说明书汇编.docx
《长整数运算说明书汇编.docx》由会员分享,可在线阅读,更多相关《长整数运算说明书汇编.docx(35页珍藏版)》请在冰豆网上搜索。
长整数运算说明书汇编
摘要
数据结构课程设计,要求学生在数据结构的逻辑特性和物理表示、数据结构的选择和应用、算法的设计及其实现等方面,加深对课程基本内容的理解。
同时,在程序设计方法以及上机操作等基本技能和科学作风方面受到比较系统和严格的训练。
而在一般的程序运算中,长整数是无法计算的,因为计算机一次能够运算的位数是有限,一旦整数很长,就需要一个程序来进行多次计算,通过长整数运算这个程序,可一把一个长整数分成多个普通整数来进行计算,使得长整数也可以进行运算。
我编写的这个程序就可以进行长整数的加减运算,各个数据也可以是负数。
关键词:
长整数;运算;加法;减法
Abstract
Datastructurecoursedesign,studentsinthelogicalcharacteristicsandphysicaldatastructurefortherepresentationofthedesign,selectionandapplicationofdatastructure,algorithmanditsrealization,deepentheunderstandingofbasiccontentofcourses.Atthesametime,bythesystematicandrigoroustraininginbasicskillsprogramdesignmethodandtheoperationandscientificstyleofwork.Butinthegeneralprogramoperation,longintegerscannotbecalculated,becausethecomputertimetooperationnumberislimited,oncetheintegerislong,needaprogramtocalculateseveraltimes,operationofthisprogramthroughthelonginteger,canputalongintegerintoapluralityofordinaryintegerstocalculate,thelongintegercanbecalculated.ThisprogramIwrotetolongintegeradditionandsubtraction,alldatacanbenegative.
Keywords:
longinteger;arithmetic;additive;subtraction
目录
1概述1
1.1题目内容1
1.2需求分析1
1.3设计要求1
2概要设计3
2.1设计分析3
2.2功能模块介绍3
2.3函数介绍4
2.4数据结构介绍5
3详细设计6
3.1程序流程介绍6
3.2函数功能介绍6
3.2.1主函数6
3.2.2插入函数8
3.2.3读入数据并插入对应的链表函数9
3.2.4输出函数10
3.2.5加法函数10
3.2.6判断俩正数大小函数12
3.2.7减法函数13
4调试分析15
4.1使用说明15
4.2测试结果15
5总结19
参考文献20
致谢21
附录22
1概述
1.1题目内容
题目:
长整数运算
内容:
使用双向循环链表存储长整数,每个结点含一个整型变量,主要功能有:
长整数输入(建立双向循环链表)、长整数的加法、长整数的减法及结果的显示输出等。
1.2需求分析
1.本程序实现计算任意长的整数的加法运算.以用户和计算机对话的方式,即在计算机终端上显示“提示信息”之后,由用户在键盘上输入演示程序中规定的运算命令,然后程序就计算并显示出这两个数的运算。
2.本程序中,集合的元素限定为数字字符[‘0’~’9’]和字符‘,’与‘;’,输入字符可以任意长,输入形式以“回车符”为结束标志,串中字符顺序不限,且允许出现重复字符。
3.现实长整数的分组存储,每个结点含一个整形变量。
输入的形式以回车结束,可以直接输入正数或负数。
按中国对于长整数的表示习惯,每四位一组,除数字和位于首位置的负号外,其它一切字符都将作为分隔符,连续多个分隔符当一个处理。
但不使用分隔符也不影响结果。
输入和输出形式是按中国对于长整数的表示习惯,每四位一组,组间用逗号隔开,长整数位数没有上限,以分号结束长整型数据的输入。
1.3设计要求
该设计要求设计程序,实现两个任意长的整数求和及差的运算问题。
通过该题目的设计过程,可以加深理解线性表的逻辑结构、存储结构,掌握线性表上基本运算的实现,进一步理解和熟练掌握课本中所学的各种数据结构,学会如何把学到的知识用于解决实际问题,培养学生的动手能力。
详细要求:
(1)至少要用10组测试数据,算法对于这些合法的输入数据都能产生满足规格说明要求的结果;
(2)算法对于精心选择的典型、苛刻而带有刁难性的几组输入数据能够得出满足规格说明要求的结果;对算法实现过程中的异常情况能给出有效信息;
(3)任何整型变量的范围是-(215-1)~(215-1)。
输入和输出形式:
按中国对于长整数的表示习惯,每四位一组,组间用逗号隔开,例1,0000,00
00,0000;而输入为1,0001,0001和-1,0001,0000实现加法时,应输出"1";
(4)较高要求:
使程序在整型量范围是-(2n-1)~(2n-1)的计算机上都能有效地运行。
其中,n是由程序读入的参量。
2概要设计
2.1设计分析
我们首先要考虑的是如何表示长整型数。
按照传统习惯要求每4位数形成1组,而一个长整型数可能会有很多组这种4位数,而每节之间是有先后顺序的,因此我们可以考虑用数组和链表来存储数据。
(1)再考虑到每个长整型数的长度在输入之间是无法预知的,因此使用链表在存储空间的分配上更方便一些。
(2)在输入数据时总是从高位到低位地存储,而计算时总是从低位向高位运算,因此采用双向链表更方便,而为了从头结点方便地转到尾结点可以采用循环链表。
总之,为了实现上述功能,应以双向循环链表表示长整数,每个结点含一个整型变量,且仅绝对值不超过9999的整数,整个链表用十进制数表示。
(3)对于每一个长整型数可以设置一个头结点,其中的数据域用来表示该长整型数的正负号及组数,该值的符号则表示该长整型数的符号,该数的绝对值表示该长整型数包含的4位数的组数。
第一个存储4位数据组的结点称为首结点,而最后一个4位数据组结点称为尾结点。
为此需要两个结构数据类型:
双向循环链表和长整数,两个类型采用相同的结构,只是双向循环链表用来存储数据,长整型用表示数据的运算。
利用双向循环链表来实现对长整数的存储。
选择该数据结构来完成长整数的加减运算是因为要对长整数进行运算,需要对长整数进行存储,所以选择用链表对长整数存储,又由于存储的顺序是从左到右,而运算的顺序则是从右到左,这样位了操作方便选择循环链表,在运算过程中有进位和借位的操作,所以最终选择双向循环链表的数据结构。
2.2功能模块介绍
该程序主要由以下几大模块组成:
1.主程序模块:
主要实现对个模块的调用和界面的管理,提示用户,帮助用户快速准确的完成运算。
2.双向循环链表处理模块:
实现对数据的存储、管理,主要由voidListInitiate、intListLength等函数组成。
3.长整型数的输入输出模块:
主要由voidOutputNumber、intInputNumber等函数组成,实现数据的输入。
4.长整数运算模块:
主要由voidadd、intchange、intchange等函数组成。
也就是函数voidyunsuan(DLNode*head1,DLNode*head2,DLNode*head3,charch)实现的是正数,负数,加法,减法。
计算式共分为八种运算,在这之前我已经实现了二种运算,那么这个函数就是把这八种运算按照一定的规则转化成已经实现的二种运算来实现完整的加减法运算。
程序功能模块图如图2.1所示。
图2.1功能模块图
2.3函数介绍
voidListInitiate(DLNode**head)
操作结果:
初始化一个头结点为head的双向循环链表。
intListLength(DLNode*head)
操作结果:
计算以head为头结点的链表的长度。
intListInsert(DLNode*head,inti,intx)
操作结果:
将节点数据为x的节点插到第i个位置上去。
intabs(intx)
操作结果:
绝对值函数,返回x的绝对值。
intInputNumber(DLNode*head)
操作结果:
将从键盘中接收数据并把得到的数据存入以head为头结点的链表中。
四位一存,中间以逗号区分,结束符为分号。
voidOutputNumber(DLNode*head,intsign)
操作结果:
将以head为头结点的链表中的所有数据输出到显示屏上。
voidadd(DLNode*head1,DLNode*head2,DLNode*head3)
操作结果:
实现正数加正数的加法操作。
intchange(DLNode*head1,DLNode*head2)
操作结果:
判断存在俩个链表中的数的大小,如何head1中的数大于head2中的数那么返回值为0,反之返回值为1,相等时返回值为2。
voidminus(DLNode*head1,DLNode*head2,DLNode*head3)
操作结果:
计算正数减正数的减法运算。
voidmain()
操作结果:
主函数。
调用以上的各个函数来引导用户进行长整数的加法运算,加法运算.。
2.4数据结构介绍
本次课设所使用的数据结构双向循环链表的节点由三个部分组成,第一是数据部分data存储此节点的数据,第二是此节点的前驱指针部分*prior指向此节点的前驱,第三是此节点的后继指针部分*next指向此节点的后继。
数据部分我们约定它为整形变量,前驱后继指针均为结构体Node类型。
代码如下:
typedefstructNode//双向链表的结构体定义
{intdata;
structNode*prior;
structNode*next;
}DLNode;
3详细设计
3.1程序流程介绍
由上面的提到的主程序、长整数运算、长整数输入输出、双向循环链表等几个主要模块,可得到程序运行图如下:
Y
N
图3.1主程序流程图
3.2函数功能介绍
3.2.1主函数
主要的作用是为用户做一个提示,如何完成自己想要的运算。
同时调用各个函数实现运算。
代码如下:
voidmain()
{intn;
charch,ch1,m;
while
(1)
{DLNode*a,*b,*c;
ListInitiate(&a);
ListInitiate(&b);
ListInitiate(&c);
printf("\n---------------长整数运算--------------\n\n");
printf("请输入数A(以分号结束):
");
InputNumber(a);
printf("请输入数B(以分号结束):
");
InputNumber(b);
printf("请选择操作符:
<+,->:
");
do
{scanf("%s",&ch1);
if(ch1=='+'||ch1=='-')
{yunsuan(a,b,c,ch1);
OutputNumber(c,1);
break;
}
else
{printf("\n此版本不支持%c运算!
是否重新输入运算符?
(y/n):
",ch1);
scanf("%s",&m);
if(m=='Y'||m=='y'){n=2;printf("\n请输入运算符'-'或'+':
");}
elsebreak;
}
}
while(n=2);
printf("\n要继续新的运算吗?
(y/n):
");
scanf("%s",&ch);
if(ch=='Y'||ch=='y')
{printf("\n");system("cls");
continue;
}
elseexit(0):
}
}
3.2.2插入函数
已知一双向链表,在第i个位置插入data为x的节点。
函数需要注意的是在什么位置插入才是合法的,在就是在该节点指针时的顺序不要搞错。
代码如下:
intListInsert(DLNode*head,inti,intx)//双向链表的数据插入,i表示是插入的第几个元素
{DLNode*p,*s;
intj;
p=head->next;
j=0;
while(p!
=head&&jnext;j++;}
if(j!
=i){printf("\n插入位置不合法!
");return0;}
if((s=(DLNode*)malloc(sizeof(DLNode)))==NULL)exit(0);
s->data=x;
s->prior=p->prior;//插入
p->prior->next=s;
s->next=p;p->prior=s;
return1;
}
3.2.3读入数据并插入对应的链表函数
实现从键盘上得到数据根据三种情况进行不同的处理,判断是否是头结点,判断是否是整数,判断输入的字符是否是“;”分号。
并且如果是正整数它的头结点data等于1否则为0。
代码如下:
intInputNumber(DLNode*head)//读入输入的数据
{intinput,i=0;//第i个节点
charc;
scanf("%d%c",&input,&c);
while
(1)
{if(input<0&&i==0)//输入数为负且是第一个节点
{head->data=0;//将长整数的符号保存在头结点中
ListInsert(head,i,input);//插入数据
}
elseif(input>=0&&i==0)//输入数为正且是第一个节点
{head->data=1;//将长整数的符号保存在头结点中
ListInsert(head,i,input);//插入数据
}
else
{if(head->next->data>=0)
ListInsert(head,i,input);//非第一个节点
else
ListInsert(head,i,input);
}
i++;
if(c==';')break;//遇到数据输入完成标志,跳出循环
scanf("%d%c",&input,&c);
}
return1;
}
3.2.4输出函数
实现将最后的结果输出到显示屏上,经过判断数据的正负和数据的范围来进行不同的处理,以保证在显示屏上显示的是正确的格式。
代码如下:
voidOutputNumber(DLNode*head,intsign)//从表尾输出数据元素
{DLNode*r=head->next;
while(r->data==0&&r!
=head->prior)
{r=r->next;}
if(sign==1)printf("结果是:
");
elseprintf("结果是:
-");
printf("%d",r->data);
r=r->next;
while(r!
=head)
{if(r->data<10)printf(",000%d",r->data);
elseif(r->data<100)printf(",00%d",r->data);
elseif(r->data<1000)printf(",0%d",r->data);
elseprintf(",%d",r->data);
r=r->next;
}printf("\n");
}
3.2.5加法函数
实现两个正数之间的相加运算,主要的算法和我们手算加法是一样的,首先设置一个进位计数的变量,根据存储的特点从低位开始相加带上进位即可得出相应的位和,最后更新进位变量。
处理边界状况:
如果两个链表一样长同时他们最高位在计算完成时仍然会有进位,那么应该考虑到在数据的更高位插入一个1表示最后的计算结果,这样才可以保证数据的完整性。
代码如下:
voidadd(DLNode*head1,DLNode*head2,DLNode*head3){
intz=0,e;
DLNode*p1,*p2;
p1=head1->prior;
p2=head2->prior;
while(p1!
=head1&&p2!
=head2)
{e=p1->data+p2->data+z;
if(e>=10000)
{z=1;e=e%10000;}
elsez=0;
ListInsert(head3,0,e);
p1=p1->prior;p2=p2->prior;
}
if(p1==head1&&p2!
=head2)
{while(p2!
=head2)
{e=p2->data+z;
if(e>=10000){z=1;e=e%10000;}
elsez=0;ListInsert(head3,0,e);
p2=p2->prior;
}
if(z==1)ListInsert(head3,0,z);
}
elseif(p1!
=head1&&p2==head2){
while(p1!
=head1)
{e=p1->data+z;
if(e>=10000){z=1;e=e%10000;}
elsez=0;
ListInsert(head3,0,e);
p1=p1->prior;
}if(z==1)ListInsert(head3,0,z);
}
else{if(z==1)ListInsert(head3,0,z);}
}
3.2.6判断俩正数大小函数
实现判断俩个正数的大小。
考虑俩正数的在链表中所占存储单元的多少,多的一定大,当他们一样长时,一位一位的比较直到找到一个节点中的data比另一个链表的对应节点的data大为止。
如果最后仍是一样大那么这两个数就是一样大的。
返回值为自己约定的参数r等于2表示俩数一样大,等于1表示第二个数大,等于0表示第一个数大。
代码如下:
intchange(DLNode*head1,DLNode*head2)
{intlength1,length2,r=2;
length1=ListLength(head1);
length2=ListLength(head2);
DLNode*p1,*p2;
p1=head1->next;
p2=head2->next;
if(length1>length2)
{r=0;returnr;}
elseif(length1 {r=1;returnr;} else {inti=0; for(i=0;i {if(p1->data>p2->data) {r=0;returnr;break;} elseif(p2->data>p1->data) {r=1;returnr;break;} else {p1=p1->next;p2=p2->next;r=2;} } }returnr; } 3.2.7减法函数 实现两个正数的减法运算。 整个函数分为俩大部分,第一部分处理第一个数大于第二个数,第二部分是处理第二个数大于第一个数。 代码如下: voidminus(DLNode*head1,DLNode*head2,DLNode*head3) {intz=0,x=-1,e; DLNode*p1,*p2; p1=head1->prior; p2=head2->prior; x=change(head1,head2); if(x==0) {while(p1! =head1&&p2! =head2) {p1->data=p1->data+z; if(p1->data>=p2->data) {e=p1->data-p2->data; ListInsert(head3,0,e); p1=p1->prior;p2=p2->prior; z=0; } else {e=10000+p1->data-p2->data; ListInsert(head3,0,e); p1=p1->prior;p2=p2->prior; z=-1; } } p1->data=p1->data+z; while(p1! =head1) {e=p1->data; ListInsert(head3,0,e); p1=p1->prior; } } elseif(x==1) {p2=head1->prior;p1=head2->prior; while(p1! =head2&&p2! =head1) {p1->data=p1->data+z; if(p1->data>=p2->data) {e=p1->data-p2->data; ListInsert(head3,0,e); p1=p1->prior;p2=p2->prior; z=0; } else {e=10000+p1->data-p2->data; ListInsert(head3,0,e); p1=p1->prior;p2=p2->prior; z=-1;} } p1->data=p1->data+z; while(p1! =head2) {e=p1->data; ListInsert(head3,0,e); p1=p1->prior; } head3->next->data=-1*head3->next->data; } else{head3->next->data=0;} } 4调试分析 1.由于对任意长整数运算的算法推敲不足,是程序调试时费时不少。 2.本程序有些代码重复出现,从而减少了空间的利用率和增加了程序代码的杂乱
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 整数 运算 说明书 汇编