1、课程设计 长整数四则运算课程设计实验报告:1.4 长整数四则运算题目:长整数四则运算一、实验内容【问题描述】 设计一个实现任意长的整数进行加法运算的演示程序【基本要求】利用双向循环链表实现长整数的存储,每个结点含一个整形变量。任何整形变量的范围是 -(215 - 1)(215 - 1)。输入和输出形式:按中国对于长整数的表示习惯,每四位一组,组间用逗号隔开。【实现基本功能】(i)是想长整数的四则运算;(ii)实现长整数的乘方和阶乘运算;(iii)整形量范围是-(2n-1)(2n-1),其中n是由程序读入的参量。输入数据的分组方法另行规定;【实现加强版本的功能】(i)四则运算在原来版本的基础上支
2、持小数运算,除法还可以通过输入整数后加小数点与相应要求取的精确位数求出精确值,如:求取3666除以7的后三位精确值,可以在输入时将除数输入为3666.000或3666.0000,就能得出相应的精确位数,当然求取后,没有余数的输出;(ii)乘方的功能也进行了强化,支持小数操作;(iii)添加了多个出错处理(即输入重操作)对相应数据输入与输出进行提示;【加强版的实现原理】(i)加减法运算加强:在原来版本的基础上依照基本的加减法操作将数据用小数点进行分隔,记录下连个输入数的小数位长度,并将小数位较短的一个数据后补0直至小数位数相同,然后用函数处理输出的数据;(ii)乘除法、乘方:其处理方法较为简单,
3、主要是记录数据中小数位数的长度,然后通过每种运算方式不同的运算原理截取小数位,再按照输出格式将数据处理进行输出;(iii)根据定义,阶乘保持不变;【特色分析】(i)加强版程序加上了简单的声音提示,无论是输入与输出均会有八个音符的其中之一对输入与输出与否进行提示,同时在输入输出数据出错时,还会用三个音符对重输入进行提示,增强了人性化操作;【测试数据】 (1)0;0;应输出“0”。 (2)-2345,6789;-7654,3211;应输出“-1,0000,0000”。 (3)-9999,9999;1,0000,0000,0000;应输出“9999,0000,0001”。 (4)1,0001,000
4、1;-1,0001,0001;应输出“0”。 (5)1,0001,0001;-1,0001,0000;应输出“1”。 (6)-9999,9999,9999;-9999,9999,9999;应输出“1,9999,9999,9998”。 (7)1,0000,9999,9999;1;应输出“1,0001,0000,0000”。二、实验目的、熟悉掌握双向循环链表的基本操作;、熟悉任意长字符串的输入,并实现把字符串转化为整数;、熟悉任意长整数的加法运算;、更进一步掌握有关类的操作 3、实验文档: 长整数四则运算需求分析 (i)本程序实现计算任意长的整数的加法运算. 以用户和计算机对话的方式,即在计算机终
5、端上显示“提示信息”之后,由用户在键盘上输入演示程序中规定的运算命令,然后程序就计算并显示出这两个数的运算。 (ii)本演示程序中,集合的元素限定为数字字符09和字符,与;,输入字符可以任意长,输入形式以“回车符”为结束标志,串中字符顺序不限,且允许出现重复字符。 (iii)利用双向循环链表现实长整数的存储,每个结点含一个整形变量。输入的形式以回车结束,可以直接输入正数或负数。按中国对于长整数的表示习惯,每四位一组,除数字和位于首位置的负号外,其它一切字符都将作为分隔符,连续多个分隔符当一个处理。但不使用分隔符也不影响结果。 (iv)自行定义的测试数据 (1)0; 0; 输出“0”; (2)-
6、2345,6789;;-7654,3211;;加法输出 “-1,000,000”; (3)-9999,9999;;1,0000,0000,0000;;加法输出 “9999,0000,0001”; (4)1,0001,0001;;1,0001,0001; 减法输出 “0”; (5)1,0001,0001;;1,0001,0000;;减法输出 ”1”; (6)-9999,9999,9999;;-9999,9999,9999; 加法输出“-1,9999,9999,9998”; (7)1,0000,9999,9999; 1; 加法输出 1,0001,0000,0000;(8)10;8;乘方输出1,00
7、00,0000;(9)-98,9997;3;除法输出-32,9999;(10)6;阶乘输出720;四、概要设计为实现上述程序功能,应以双向循环链表表示长整数。为此,需要定义一个抽象数据类型。1、抽象数据类型定义为:ADT OrderedOperation数据对象:D=ai|aiint,i=1,2,.n, n0数据关系:R1=|ai-1,aiD|=2,n 基本操作:Status conversion(str,oprh)/操作结果:输入转换函数,将字符串形式的操作数转换成所需的类型cmplinklen( opr1, opr2)/操作结果:比较链表长度函数,opr1链比opr2链长则返回1,短则返回
8、-1,否则返 /回0length( oprr)/操作结果:求链表长度Status Creat(oprr,len)/操作结果:生成指定长度链表compare(opr1,opr2)/操作结果:比较opr1、opr2绝对值的大小Status init(oppr)/初始化链表函数Status distroy(oprr)/销毁链表函数Status evaluate(opri,i)/操作结果:链表短赋值函数,将i的值转换成万进制类型,i为整形变量Status add_bas(opr1,opr2,oprr)/操作结果:加法基本操作,本算法实现A,B相加的操作。 Status sub_bas(opr1,opr
9、2,oprr)/减法基本操作,本算法实现A,B相减的操作Status add(opr1,opr2,oprr)/操作结果:带符号加法运算 Status sub(opr1,opr2,oprr)/操作结果:带符号减法函数Status imul(opr1,opr2,oprr)/操作结果:乘法运算Status idiv(opr1,opr2,quti,remand)/操作结果:除法运算Status imul_power(opr1,n,oprr)/操作结果:乘方运算,运用了二分思想,时间长度为lgN Status imul_factorial(opr1,oprr)/操作结果:阶乘运算Status outpu
10、t(oprr,str)/操作结果:输出的数据按四位一组,分隔符为,的格式ADT OrderedOperation链表抽象数据类型的定义:ADT List数据对象:D=ai|aiElemSet, i=1,2, ,n, n0数据关系:R1=|ai-1,aiD, i=1,2, ,n 基本操作:Status initbuf(char str)/操作结果:缓冲区部分初始化函数,返回OKint cmplinklen(NodeList opr1,NodeList opr2)/操作结果:opr1链比opr2链长则返回1,短则返回-1,否则返回0 int length(NodeList oprr) /操作结果:
11、计算链表长度,并返回链表长度的操作数 Status Creat(NodeList &oprr,int len) /操作结果:生成指定长度链表,返回OK int compare(NodeList opr1,NodeList opr2) /操作结果:比较opr1、opr2绝对值的大小 Status init(NodeList &oppr) /操作结果:初始化链表函数 Status distroy(NodeList &oprr) /操作结果:销毁链表函数,返回OK Status evaluate(NodeList &opri,int i) /操作结果:链表短赋值函数,将i的值转换成万进制类型,i为整
12、形变量ADT OrderedList2、本程序大体包含三个模块:(i)主程序模块: void main() 初始化; do 接受命令; 处理命令; while(“命令”=”退出”)(ii)集合单元模块实现集合的抽象数据类型 (iii)结点结构单元模块定义集合的结点结构各模块之间的关系如下:3、本程序细分为以下几大功能模块:(i)输入模块;(ii)输出模块;(iii)预处理及相关操作模块(iv)四则预算模块及(包含乘方、阶乘);(v)主操作模块;五、详细设计(伪代码)1、头文件的定义部分#include #include#include#include#include#include#defin
13、e LEN sizeof(struct Node)#define MAX 1000#define OK 1#define ERROR 0#define OVERFLOW -1#define TRUE 1#define FALSE 0typedef char _TCHAR; typedef int Status;2、输入模块:/求指数函数值int axp(int a,int k) if(k=0) return 1; /k指数为零的情况 for(;k0;k-) /指数结果处理 r=r*a; return r;/输入转换函数Status conversion(char str,NodeList &o
14、prh)/将字符串形式的操作数转换成所需的类型 k=buffer=0; oprh=(NodeList)malloc(LEN); /申请长整数由字符串转换为链表的存储空间 oprh-next=oprh; oprh-prior=oprh;/初始化链表的前驱指针prior指针与后驱指针next for(i=strlen(str)-1;i=0;i-) /出错判断处理,规范输入格式;若输入格式出错,则跳出转换程,并序重新输入 if(stri!=- & stri!=+) buffer=buffer+(stri-0)*axp(10,k); k+; if(k=4 | stri-1=- | stri-1=+ |
15、 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; /根据字符串输入的首位字符,确定链表的数据类型是正整数还是负整数,返回OK/输入函数Status input(NodeList &opr1,NodeList &opr2,char str) /分别输入连个字符串并进行判断,直至输入成功则返回OKStatus input1(NodeList &opr1,int &n,char
16、str) /分别输入乘方的底数和指数两个操作数,直至输入成功返回OKStatus input2(NodeList &oprr,char str) /只是输入阶乘的一个正整数,直至输入成功返回OK3、输出模块:/输出函数Status output(NodeList oprr,char str) if(!oprr) return ERROR; /判断用链表记录的运算结果是否为空(出错),返回FALSE p=oprr; /指针对链表进行遍历 initbuf(str); /清空字符串数组str的内容 /符号位判断,若为负数,在字符串的首位加 p=p-next; if(p-next=oprr & p-d
17、ata=0)/若要输出的数为0则执行 stri+=0; else while(p!=oprr) /每千位进行取余数运算 while(jnext; p2=opr2-next; /取指针进行操作 if(cmplinklen(opr1,opr2)=1)/opr1比较长 return 1; else if(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; /比较长度
18、,分别返回操作值-1,0,1 Status init(NodeList &oppr) /初始化链表函数Status distroy(NodeList &oprr) /销毁链表函数,返回OK/distroyStatus evaluate(NodeList &opri,int i)/链表短赋值函数,将i的值转换成万进制类型,i为整形变量 opri=(NodeList)malloc(LEN); opri-data=+; opri-next=(NodeList)malloc(LEN); opri-next-data=i; opri-next-next=opri; opri-prior=opri-nex
19、t; opri-next-prior=opri; return OK;/evaluate5、加减法模块/加法基本操作Status add_bas(NodeList opr1,NodeList opr2,NodeList &oprr)/本算法实现A,B相加的操作。 oprr=(NodeList)malloc(LEN); /初始化前驱指针prior与后驱指针next,并用p1,p2进行指针操作 CF=buffer=0; while(p1!=opr1 & p2!=opr2) buffer=p1-data+p2-data+CF; CF=buffer/10000;/若buffer的值大于9999则产生进
20、位,赋给CF /将新建结点插入到头结点之后 p3=(NodeList)malloc(LEN); /结点存储空间 oprr-next-prior=p3; /前驱指针与后驱指针互换 p3-data=buffer%10000;/应该将buffer的第四位赋给p3-data /. /指针进入下一个双向链表的结点 while(p1!=opr1) /处理opr1链的剩余部分 buffer=p1-data+CF; CF=buffer/10000; /将新建结点插入到头结点之后 p3=(NodeList)malloc(LEN); oprr-next-prior=p3; p3-prior=oprr; p3-ne
21、xt=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-data=buffer%10000; /. p2=p2-prior; if(CF) /判定进位,并进行进位操作 p3=(NodeList)malloc(LEN); oprr-next-
22、prior=p3; p3-prior=oprr; p3-next=oprr-next; oprr-next=p3; p3-data=CF; /添加长整数类型符号,并返回OK/减法基本操作Status sub_bas(NodeList opr1,NodeList opr2,NodeList &oprr)/本算法实现A,B相减的操作。 /将A链分成与B链长相等的底位部分,和剩余的高位部分,并做相应处理。 oprr=(NodeList)malloc(LEN); /前驱指针prior与后驱指针next置空,并用p1,p2进行指针操作 CF=buffer=flag=0; while(p2!=opr2)
23、/opr2链的长度小于等于opr1链的 if(p1-datadata+CF) /判断进位CF,并进行进位操作 p3=(NodeList)malloc(LEN); oprr-next-prior=p3; /前驱指针与后驱指针互换 p3-data=buffer; p1=p1-prior; p2=p2-prior; while(p1!=opr1) /处理opr1链剩下的部分 if(p1-datanext-prior=p3; /前驱指针与后驱指针互换 p3-data=buffer; p1=p1-prior; /处理链表开头结点值为0的无意义情况,若链表本身表示0,则不做如下处理 p3=oprr-nex
24、t; 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) /释放无用结点 qq=qh; qh=qh-next; free(qq); /- /添加符号,返回OK/带符号加法函数Status add(NodeList opr1,NodeList opr2,NodeList &oprr) /出错处理:若opr1或opr2为空,返回FALSE
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1