长整数,高精度大数加减运算课程报告(c++版)(附源代码)_第1页
长整数,高精度大数加减运算课程报告(c++版)(附源代码)_第2页
长整数,高精度大数加减运算课程报告(c++版)(附源代码)_第3页
长整数,高精度大数加减运算课程报告(c++版)(附源代码)_第4页
长整数,高精度大数加减运算课程报告(c++版)(附源代码)_第5页
已阅读5页,还剩62页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、华南理工大学 计算机学院网络工程 Copyright 201 by CY.M.华南理工大学高级语言程序设计 I 大作业报告实验题目: 长整数运算、高精度运算 姓名: 李超悦 学号: 201230610155 班级: 网络工程 任课教师: 郑运平实验概述【实验目的及要求】 设计一个程序实现两个任意长的整数(包括正数和负数)、任意精度实数的算术运算。要求:(1) 用动态链表存贮数据,每个结点含一个整型变量,表示若干位数。( 注:任何整型变量的范围是 (231 1)(231 1),任意长整数的整型变量的范围是(2n 1)(2n1),在计算机上都能有效地运行。 其中,n是由程序读入的参数控制的。 )(

2、2)整数输入和输出按中国对于长整数的习惯表示,每3位1组,组间用逗号隔开。(3)实现加、减运算。(4)程序运行界面清晰实用。【实验原理】 大整数的存储结构:大数计算的因数和结果精度一般是少则数十位,多则几万位。在C+语言中定义的类型中精度最多只有二十多位,因而我们采取用链表存贮的方式来存放大数。在计算中会用到从高位开始计算,和从低位开始计算数值的两种情况。所以我们将链表定义为双向链表,其中为一个单元来存贮数据,一个指针指向前方的数据,另一个指向后的数据。程序的逻辑框图双向链表的初始化主函数输入任意长整数调用双向链表基本操作函数长整数求值及结果显示END【实验环境】 VS2012 SP2,WIN

3、8平台实验内容【实验方案设计】一、要求和规格的说明描述问题:设计一个程序实现两个任意长的整数(包括正数和负数)、任意精度实数的算术运算。要求:(1) 用动态链表存贮数据,每个结点含一个整型变量,表示若干位数。( 注:任何整型变量的范围是 (231 1)(231 1),任意长整数的整型变量的范围是(2n 1)(2n1),在计算机上都能有效地运行。 其中,n是由程序读入的参数控制的。 )(2)整数输入和输出按中国对于长整数的习惯表示,每3位1组,组间用逗号隔开。(3)实现加、减运算。(4)程序运行界面清晰实用。二、设计1、 设计思想:1) 储结构:双向链表储存数据struct long_int/构

4、建一个存储字符与地址的结构 char num ; long_int *pro , *next ; ;/在这里,用pro记录左链,用next记录右链原理:在C+语言中定义的类型中精度最多只有二十多位,因而我们采取用链表存贮的方式来存放大数。在计算中会用到从高位开始计算,和从低位开始计算数值的两种情况。所以我们将链表定义为双向链表,其中为一个单元来存贮数据,一个指针指向前方的数据,另一个指向后的数据。2) 主要算法思想。A加法:先从低位算起,因为只须要对应的位相加,再加上前一位的进位,再去判断是否本位是否有进位, 有则把本位数字改为减去它的权,也就是10,再置进位为1。如果没有进位,则给进位赋值0

5、。两个加数中那一个数的位数长,以位数长的作为循环变量;用ASCLL码值做判断;此处以一位为一储单元,实现进位,提高运算效率,再将数字三位一组加“,”,写入字符串,方便输出代码实现:/加法运算string Plus ( long_int*& num1 , long_int*& num2 , long_int*& num_1 , long_int*& num_2 , int sign )/运行加法运算int n , i=0 , k=0 ;/这里定义i为进位判断符号,k为间隔符判断符号long_int *s , *p , *q , *head = NULL ;/在这里,head只能算是指向小数点的标

6、志了if ( num_1 | num_2 ) s = new long_int ;/存储小数点的链s-num = . ;head = s ;p = s ;while ( num_1 | num_2 )if ( k != 0 & k % 3 = 0 )/k作为判断位数间隔,每3个位一个“,”s = new long_int ;s-num = , ;p-next = s ;s-pro = p ;p = s ;s = new long_int ;s-pro = p ; if ( num_1 = NULL | num_2 = NULL )/当其中一个数位数不够时的判断if ( num_1 = NULL

7、 ) n = num_2-num ;else n = num_1-num ;else n = num_1-num + num_2-num - 48 ;/因为运算的是ASCLL码,所以减去48,即重复的部分if( n 9 )/当ASCLL码超出57说明要进位了n -= 10 ; q = s ;while( q-pro-num != . )/进位的判断,这里从高位加到低位,所以进位的时候得从低位到高位判断回去if ( q-pro-num = , ) q = q-pro ;/发现间隔符就跳过q-pro-num += 1 ;if ( q-pro-num 9 )/对下一位进位的判断q-pro-num -

8、= 10 ;q = q-pro ;else break ;if ( q-pro-num = . ) i+ ; s-num = n ; k+ ;if ( num_1 ) num_1 = num_1-next ;if ( num_2 ) num_2 = num_2-next ;p-next = s ; p = s ;p-next = NULL ;p = head ;/把这次标志初始化k = 0 ;while ( num1 | num2 )if ( k != 0 & k % 3 = 0 )/k作为判断位数间隔,每3个位一个“,”s = new long_int ;s-num = , ;p-pro =

9、 s ;s-next = p ;p = s ;s = new long_int ;if ( num1 = NULL | num2 = NULL )/当其中一个数位数不够时的判断if ( num1 = NULL ) n = num2-num + i ;else n = num1-num + i ;else n = num1-num + num2-num -48 + i ;/因为运算的是ASCLL码,所以减去48,即重复的部分i = 0 ;if ( n 9 )/当ASCLL码超出57说明要进位了n-=10 ; i+ ;/i作为进位的判断s-num = n ; k+ ;if( num1 )num1

10、= num1-pro ;if( num2 )num2 = num2-pro ;if( head=NULL )/判断是否建立了表头 head = s ; s-next = NULL ; else p-pro = s ; s-next = p ; p = s ;if ( i = 1 )/当较大数的最高位有进位时,在这里另行分析if ( k % 3 = 0 )/同样先判断是否需加间隔符“,”s = new long_int ;s-num = , ;p-pro = s ;s-next = p ;p = s ;s = new long_int ;s-num = 49 ;/ASCLL码49即是1p-pro

11、 = s ;s-next = p ;p = s ;p-pro = NULL ;string str = Output ( p ) ;/输出结果if ( sign ) str = str.insert(0,-);return str;B减法:减法运算技巧:将减数换符号,做加法,不再累述2、 设计表示: 1) 函数头和规格说明 算法部分函数头功能struct long_int定义双向链表存储结构struct long_int *creat()创建带有头结点的空链表string Output ( long_int*&numb )打印输出函数void Judge ( char& s , int sym

12、_a , int sym_b , int& sign )符号判断函数int get ( string & str , long_int*& number , long_int*& num )长整数格式转换函数string Plus ( long_int*& num1 , long_int*& num2 , long_int*& num_1 , long_int*& num_2 , int sign )/运行加法运算长整数加法运算函数string Minus ( long_int*& num1 , long_int*& num2 , long_int*& num_1 , long_int*& n

13、um_2 , int sign )长整数减法运算函数 窗体部分函数头功能System:Void button5_MouseClick(System:Object sender, System:Windows:Forms:MouseEventArgs e)重置按钮private:System:Void button7_MouseClick(System:Object sender, System:Windows:Forms:MouseEventArgs e)退出按钮private:System:Void comboBox1_SelectedIndexChanged(System:Object s

14、ender, System:EventArgs e)初始化单选框1private: System:Void run_Click(System:Object sender, System:EventArgs e)运算功能实现(主)private: System:Void radioButton1_CheckedChanged(System:Object sender, System:EventArgs e)单选框1设置private: System:Void radioButton2_CheckedChanged(System:Object sender, System:EventArgs e)

15、单选框2设置private: System:Void save_Click(System:Object sender, System:EventArgs e)储存对话框设置private: System:Void saveFileDialog1_FileOk(System:Object sender, System:ComponentModel:CancelEventArgs e)储存文本private: System:Void textBox1_DoubleClick(System:Object sender, System:EventArgs e)清除textBox1原有输入private

16、: System:Void textBox2_DoubleClick(System:Object sender, System:EventArgs e)清除textBox2原有输入private: System:Void Form1_Load(System:Object sender, System:EventArgs e)调用存储文本对话框2) 函数调用关系图 如图所示【实验过程】(实验步骤、记录、数据、分析)1) 调试报告: 录入负数失效原因:头结点未做分类处理解决方法:加入头节点处理函数,如下if( stri = - )/判断该数的正负,存储数据的符号i+ ;sym = 1 ;else

17、if ( stri = + ) i+ ;s-num = stri ;s-pro = NULL ;/向左建立链表,让个位数做表头,方便计算i+ ; 整形无法转换为字符型输出出现问题解决方法:调用itoa()转换函数 string s;char t4=;itoa(p-data, t,10);/整形转换为字符串 视窗输入输入非数字字符时崩溃解决方法:设置事件检验for(i=0;iSubstring(i,1);x = (int)Char:Parse(strtemp1) -48;if(x-3&x9) String z=输入格式错误,只可输入数字,请勿输入回车(双击清除消息);textBox1-Clear

18、();textBox1-Text=z;goto end; 1System:String无法转化为char*解决方法:设置转换函数#include System:Runtime:InteropServices;char*s2 = (char*)Marshal:StringToHGlobalAnsi(str2).ToPointer(); /System:String转换为char*strb = s2; /char*转换为string;2 System:String无法转化为std:string解决方法:设置转换函数String st = gcnew String(s.c_str(); /std:s

19、tring 转成System.StringConsole:WriteLine(st); 2) 测试数据: 123,456,789,012,345,678,90+123,456,789,012,345,678,90(测试加法)运算结果:24,691,357,802,469,135,780正确 678,454,454,454,777-87,789,746,464(测试减法)测试结果:678,454,366,664,708,313正确3) 实现注释: 实现了任意长度长整数的加减运算附加功能:制作应用程序视窗,是操作简洁明了 实现数据保存功能,方便大数据记录4) 用户手册:大数加减运算器用户手册 选择

20、“大数运算.exe”开始程序 界面如下图所示 1在文本框里输入测试数据(123,456,789,012,345,678,90+123,456,789,012,345,678,90)可以用逗号(“,”)隔开,方便记位2选择+(加法)或-(减法)(默认为加法) 点击“运算”按钮,进行运算,得到结果 1可选“保存运算”,弹出保存信息框2选择保存格式(推荐使用word 文档(*.doc)格式),保存3查看保存信息 重置继续进行运算或退出 版权声明更多使用方法请参见:帮助视频(大数运算).mp45) 附:/Form1.h /操作函数部分#pragmaonce usingnamespaceSystem:I

21、O;usingnamespaceSystem:Runtime:InteropServices;usingnamespacestd;#defineLENsizeof(structlong_int)/定义结点大小structlong_int/构建一个存储字符与地址的结构charnum;long_int*pro,*next;/在这里,用pro记录左链,用next记录右链 intget(string&str,long_int*&number,long_int*&num)/str为输入的字符串number为带出的整数字符串链表表头num为小数部分表头inti=0,sym=0;long_int*s,*p;

22、s=newlong_int;if(stri=-)/判断该数的正负,存储数据的符号i+;sym=1;elseif(stri=+)i+;s-num=stri;s-pro=NULL;/向左建立链表,让个位数做表头,方便计算i+;/控制各个位数的字符while(stri&stri!=.)p=s;s=newlong_int;s-num=stri;s-pro=p;i+;number=s;p=NULL;/重新对p初始化if(stri=.)/在这里我另外建立一个链表来存储小数部分i+;while(stri)s=newlong_int;if(num=NULL)num=s;/在这里向右建立链表,因为小数点的关系,

23、计算时打算从左算到右elsep-next=s;s-num=stri;p=s;i+;if(str.find(.)=str.length()-1)str=str.erase(str.length()-1,1);returnget(str,number,num);/判断结构完整性p-next=NULL; returnsym;/函数返还的是该数的符号,为下面符号判断用 stringOutput(long_int*&numb)strings=;while(numb)/遍历输出s=s+numb-num;numb=numb-next;returns; voidJudge(char&s,intsym_a,in

24、tsym_b,int&sign)/该函数用来控制运算类型和结果的正负号if(s=+|s=-)if(sym_a&sym_b)sign=1;/当两个数都为负时,先把负号取出,例如:-5+(-6)变为-(5+6)elseif(s=+)s=-;/当只有一个数是负的时,先变号,例如:9-(-3)变为9+3,-5+4变为-(5-4)elses=+;if(sym_a=1)sign=1;/如果第一个数是负的,那么要取出负号,例如:-5+4变为-(5-4)return;/判断符号 /加法运算 stringPlus(long_int*&num1,long_int*&num2,long_int*&num_1,lon

25、g_int*&num_2,intsign)/运行加法运算intn,i=0,k=0;/这里定义i为进位判断符号,k为间隔符判断符号long_int*s,*p,*q,*head=NULL;/在这里,head只能算是指向小数点的标志了if(num_1|num_2)s=newlong_int;/存储小数点的链s-num=.;head=s;p=s;while(num_1|num_2)if(k!=0&k%3=0)/k作为判断位数间隔,每3个位一个“,”s=newlong_int;s-num=,;p-next=s;s-pro=p;p=s;s=newlong_int;s-pro=p;if(num_1=NULL

26、|num_2=NULL)/当其中一个数位数不够时的判断if(num_1=NULL)n=num_2-num;elsen=num_1-num;elsen=num_1-num+num_2-num-48;/因为运算的是ASCLL码,所以减去48,即重复的部分if(n9)/当ASCLL码超出57说明要进位了n-=10;q=s;while(q-pro-num!=.)/进位的判断,这里从高位加到低位,所以进位的时候得从低位到高位判断回去if(q-pro-num=,)q=q-pro;/发现间隔符就跳过q-pro-num+=1;if(q-pro-num9)/对下一位进位的判断q-pro-num-=10;q=q-

27、pro;elsebreak;if(q-pro-num=.)i+;s-num=n;k+;if(num_1)num_1=num_1-next;if(num_2)num_2=num_2-next;p-next=s;p=s;p-next=NULL;p=head;/把这次标志初始化k=0;while(num1|num2)if(k!=0&k%3=0)/k作为判断位数间隔,每3个位一个“,”s=newlong_int;s-num=,;p-pro=s;s-next=p;p=s;s=newlong_int;if(num1=NULL|num2=NULL)/当其中一个数位数不够时的判断if(num1=NULL)n=

28、num2-num+i;elsen=num1-num+i;elsen=num1-num+num2-num-48+i;/因为运算的是ASCLL码,所以减去48,即重复的部分i=0;if(n9)/当ASCLL码超出57说明要进位了n-=10;i+;/i作为进位的判断s-num=n;k+;if(num1)num1=num1-pro;if(num2)num2=num2-pro;if(head=NULL)/判断是否建立了表头head=s;s-next=NULL;elsep-pro=s;s-next=p;p=s;if(i=1)/当较大数的最高位有进位时,没想到怎么放到上面一起讨论,就在这里另行分析if(k%

29、3=0)/同样先判断是否需加间隔符“,”s=newlong_int;s-num=,;p-pro=s;s-next=p;p=s;s=newlong_int;s-num=49;/ASCLL码49即是1p-pro=s;s-next=p;p=s;p-pro=NULL; stringstr=Output(p);/输出结果if(sign)str=str.insert(0,-);returnstr; /减法运算stringMinus(long_int*&num1,long_int*&num2,long_int*&num_1,long_int*&num_2,intsign)intn;stringstr;lon

30、g_int*s,*p,*q,*num_a=num1,*num_b=num2,*num_a1=num_1,*num_b2=num_2;loop:intk=0,i=0;long_int*head=NULL;if(num_a1|num_b2)s=newlong_int;/存储小数点的链s-num=.;head=s;p=s;while(num_a1|num_b2)if(k!=0&k%3=0)s=newlong_int;s-num=,;p-next=s;s-pro=p;p=s;s=newlong_int;s-pro=p;if(num_a1=NULL&num_b2)/当被减数不够时的情况n=0-num_b

31、2-num+48;/不够用时先向高位借位先elseif(num_b2=NULL)n=num_a1-num;elsen=num_a1-num-num_b2-num+48;/48是多减去的部分if(npro-num!=.)/判断会否向整数部分借位if(q-pro-num=,)q=q-pro;q-pro-num-=1;if(q-pro-numpro-num+=10;q=q-pro;elsebreak;if(q-pro-num=.)i+;/利用i把借位传值到整数部分s-num=n;k+;if(num_a1)num_a1=num_a1-next;if(num_b2)num_b2=num_b2-next;

32、p-next=s;p=s;p-next=NULL;p=head;/把这次标志初始化k=0;while(num_a|num_b)if(k!=0&k%3=0)s=newlong_int;s-num=,;p-pro=s;s-next=p;p=s;s=newlong_int;if(num_a=NULL&num_b)/当被减数不够时的情况sign-;/sign说明符号要变num_a=num2;num_a1=num_2;/交换减数和被减数再进行一次相减num_b=num1;num_b2=num_1;gotoloop;if(num_b=NULL)n=num_a-num-i;elsen=num_a-num-n

33、um_b-num+48-i;/48是多减去的部分i=0;if(nnum=n;k+;if(num_a)num_a=num_a-pro;if(num_b)num_b=num_b-pro;if(head=NULL)head=s;s-next=NULL;elsep-pro=s;s-next=p;p=s;if(i=1)/当被减数被减完后,即是最高位需要借位时sign-;/改变符号,对调两个数再相减num_a=num2;num_a1=num_2;num_b=num1;num_b2=num_1;gotoloop;/重复运算 p-pro=NULL;while(p-num=0|p-num=,)/除去高位数上的0

34、,才不会出现像“123-123=000”的现象if(p-next!=NULL)if(p-next-num!=.)p=p-next;/判断会否去0的时候会否超过小数位elsebreak;elsestr=0;/对于结果是0的我们直接输出0就不用执行下面部分了returnstr;str=Output(p);/输出结果if(sign)str.insert(0,-);returnstr;/视窗部分namespace大数运算 usingnamespaceSystem;usingnamespaceSystem:ComponentModel;usingnamespaceSystem:Collections;u

35、singnamespaceSystem:Windows:Forms;usingnamespaceSystem:Data;usingnamespaceSystem:Drawing; /Form1摘要/publicrefclassForm1:publicSystem:Windows:Forms:Formpublic:Form1(void)InitializeComponent();/TODO:在此处添加构造函数代码/private:System:Windows:Forms:Labellabel5; public:booln;private:System:Windows:Forms:SaveFile

36、DialogsaveFileDialog1;private:System:Windows:Forms:Labellabel6;private:System:Windows:Forms:Labellabel7;private:System:Windows:Forms:PictureBoxpictureBox1;public: SaveFileDialogsave1;protected:/清理所有正在使用的资源。/Form1()if(components)deletecomponents;private:System:Windows:Forms:TextBoxtextBox1;protected:

37、private:System:Windows:Forms:TextBoxtextBox2;private:System:Windows:Forms:Labellabel1;private:System:Windows:Forms:Labellabel2;private:System:Windows:Forms:Labellabel3;private:System:Windows:Forms:TextBoxtextBox3;private:System:Windows:Forms:Labellabel4;private:System:Windows:Forms:Buttonrun;private

38、:System:Windows:Forms:Buttonclear;private:System:Windows:Forms:Buttonsave;private:System:Windows:Forms:Buttonexit;private:System:Windows:Forms:RadioButtonradioButton1;private:System:Windows:Forms:RadioButtonradioButton2; private:/必需的设计器变量。/System:ComponentModel:Containercomponents; #pragmaregionWind

39、owsFormDesignergeneratedcode/设计器支持所需的方法-不要/使用代码编辑器修改此方法的内容。/voidInitializeComponent(void)System:ComponentModel:ComponentResourceManagerresources=(gcnewSystem:ComponentModel:ComponentResourceManager(Form1:typeid);this-textBox1=(gcnewSystem:Windows:Forms:TextBox();this-textBox2=(gcnewSystem:Windows:Fo

40、rms:TextBox();this-label1=(gcnewSystem:Windows:Forms:Label();this-label2=(gcnewSystem:Windows:Forms:Label();this-label3=(gcnewSystem:Windows:Forms:Label();this-textBox3=(gcnewSystem:Windows:Forms:TextBox();this-label4=(gcnewSystem:Windows:Forms:Label();this-run=(gcnewSystem:Windows:Forms:Button();th

41、is-clear=(gcnewSystem:Windows:Forms:Button();this-save=(gcnewSystem:Windows:Forms:Button();this-exit=(gcnewSystem:Windows:Forms:Button();this-radioButton1=(gcnewSystem:Windows:Forms:RadioButton();this-radioButton2=(gcnewSystem:Windows:Forms:RadioButton();this-label5=(gcnewSystem:Windows:Forms:Label();this-saveFileDialog1=(gcnewSystem:Windows:Forms:SaveFileDialog();this-label6=(gcnewSystem:Windows:Forms:Label();this-label7=(gcnewSystem:Windows:Forms:Label();this-pictureBox1=(gcnewSystem:Windows:Forms:Pictur

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论