分数类的设计与实现有理数运算.docx
- 文档编号:11815114
- 上传时间:2023-04-03
- 格式:DOCX
- 页数:27
- 大小:366.08KB
分数类的设计与实现有理数运算.docx
《分数类的设计与实现有理数运算.docx》由会员分享,可在线阅读,更多相关《分数类的设计与实现有理数运算.docx(27页珍藏版)》请在冰豆网上搜索。
分数类的设计与实现有理数运算
课程设计任务书
学院
信息科学与工程
专业
通信工程
学生姓名
Neko
学号
10030603**
设计题目
分数类的设计与实现
内容及要求:
建立用于完成分数形式运算的类RationalNumber。
编写一个测试该类的程序。
用整数变量表示类的私有数据(即分子和分母)。
给类提供一个能够对所声明的对象初始化的构造函数。
为了能够在不提供初始化值的情况下也能对对象初始化,构造函数中应该包含默认的值。
构造函数还应该以最简分数的形式存储数据,即2/4应该在对象中存储成分子为1、分母为2的形式。
公有成员函数应该有以下功能:
(1)两个有理数相加,以最简形式保存结果;
(2)两个有理数相减,以最简形式保存结果;
(3)两个有理数相乘,以最简形式保存结果;
(4)两个有理数相除,以最简形式保存结果;
(5)以a/b的形式输出有理数(a是分子,b是分母);
(6)以浮点形式输出有理数。
进度安排:
第17周:
分析题目,查阅课题相关资料,进行类设计、算法设计;
第18周:
程序的设计、调试与实现;
第19周:
程序测试与分析,撰写课程设计报告,进行答辩验收。
指导教师(签字):
年月日
学院院长(签字)
年月日
目录
1需求分析-1-
2算法基本原理-1-
2.1加法-1-
2.2减法-2-
2.3乘法-2-
2.4除法-2-
3类设计-2-
4详细设计-3-
4.1类的接口设计-3-
4.2类的实现-4-
4.3主函数设计-9-
5DOS界面程序运行结果及分析-11-
5.1程序运行结果-11-
5.2运行结果分析-13-
6基于MFC的图形界面程序开发-13-
6.1基于MFC的图形界面程序设计-13-
6.2程序测试-22-
6.3MFC程序编写总结-25-
7参考文献-26-
1需求分析
(1)有理数可分为整数和分数也可分为三种,一;正数,二;0,三;负数。
除了无限不循环小数以外的实数统称有理数。
在数学上有理数的运用相当广泛,所以一款简易的有理数计算器可以大大节约时间,而且不会因为人为误差导致计算结果出错。
(2)依照它们的序列,有理数具有一个序拓扑。
有理数是实数的(稠密)子集,因此它同时具有一个子空间拓扑。
采用度量,有理数构成一个度量空间,这是它的第三个拓扑。
幸运的是,所有三个拓扑一致并将有理数转化到一个拓扑域。
有理数是非局部紧致空间的一个重要的实例。
这个空间也是完全不连通的。
有理数不构成完备的度量空间;实数是它的完备集。
(3)程序测试数据选择若干种有代表性的数据来进行测试,通过临界数据的测试来判断系统的正确性。
2算法基本原理
2.1加法
有理数的加法与小学的加法大有不同,小学的加法不涉及到符号的问题,而有理数的加法运算总是涉及到两个问题:
一是确定结果的符号;二是求结果的绝对值。
在进行有理数加法运算时,首先判断两个加数的符号:
是同号还是异号,是否有0。
从而确定用那一条法则。
在应用过程中,一定要牢记"先符号,后绝对值",熟练以后就不会出错了。
多个有理数的加法,可以从左向右计算,也可以用加法的运算定律计算。
法则
1.同号相加,取相同符号,并把绝对值相加。
2.绝对值不等的异号加减,取绝对值较大的加数符号,并用较大的绝对值减去较小的绝对值。
互为相反数的两个数相加得0。
3.一个数同0相加,仍得这个数。
定律
Ⅰ.同号相加,取相同符号,并把绝对值相加。
Ⅱ.绝对值不相等的异号两数加减,取绝对值较大的符号,并用较大的绝对值减去较小的绝对值。
互为相反数的两个数相加得0。
Ⅲ.一个数同0相加,仍得这个数。
Ⅳ.相反数相加结果一定得0。
2.2减法
有理数减法法则:
减去一个数,等于加上这个数的相反数。
其中:
两变:
减法运算变加法运算,减数变成它的相反数。
一不变:
被减数不变。
可以表示成:
a-b=a+(-b)。
2.3乘法
1.两数相乘,同号为正,异号为负,并把绝对值相乘。
例;(-5)×(-3)=15(-6)×4=-24
2.任何数字同0相乘,都得0.例;0×1=0
3.几个不等于0的数字相乘,积的符号由负因数的个数决定。
当负因数有奇数个数时,积为负;当负因数有偶数个数时,积为正。
并把其绝对值相乘。
例;(-10)×〔-5〕×(-0.1)×(-6)=积为正数,而(-4)×(-7)×(-25)=积为负数
4.几个数相乘,有一个因数为0时,积为0.例;3×(-2)×0=0
5.乘积为1的两个有理数互为倒数(reciprocal)。
例如,—3与—1/3,—3/8与—8/3。
2.4除法
1.除以一个数等于乘以这个数的倒数。
(注意:
0没有倒数)
2.两数相除,同号为正,异号为负,并把绝对值相除。
3.0除以任何一个不等于0的数,都等于0。
4.0在任何条件下都不能做除数。
3类设计
从上面的算法分析可以看到,本设计面临的计算问题的关键是设计一个有理数运算类。
这个类必须能将用户给定的2个整数表达成有理数,同时必须进行合法性检测。
同时需要为类设计4个方法,分别来运算加法,减法,乘法和除法,为了使有理数运算看起来更符合自然,所以必须利用C++的重载技术,来对相应的4种运算符进行重载,并且还需要设计一个方法来满足有理数分数形式和小数形式的转换。
要从用户输入创建一个有理数,为类设计了一个带有默认参数的构造函数来满足需求。
根据以上的分析,设计出CRationalNumber类。
如图1所示。
图1CRationalNumber类UML图形表示
4详细设计
整个程序分为三个独立的文档,RationalNumber.h文件中为有理数类CRationalNumber的申明,RationalNumber.cpp文件中包括有理数类的成员函数实现文件;main.cpp文件包括程序的入口函数,和测试数据。
4.1类的接口设计
//RationalNumber.h文件,实现类的声明
classCRationalNumber
{
public:
CRationalNumber(intnt=0,intdt=1);
//带有默认参数的构造函数声明
virtual~CRationalNumber();
public:
intnumtor;//分子
intdentor;//分母
CRationalNumberoperator+(CRationalNumber&rn);
//加号运算符重载函数声明
CRationalNumberoperator-(CRationalNumber&rn);
//减号运算符重载函数声明
CRationalNumberoperator*(CRationalNumber&rn);
//乘号运算符重载函数声明
CRationalNumberoperator/(CRationalNumber&rn);
//除号运算符重载函数声明
floatConvertFloat();//将有理数转换成浮点数
};
ostream&operator<<(ostream&,RationalNumber&);
//重载流插入运算符,使分数以(a/b)形式输出函数声明
类CRationalNumber设计了一个带有默认构造参数的构造函数,方便用户构造有理数。
同时设计了4个重载函数,可以让使用者像使用普通整数那样对有理数运算进行操作,大大的提高了使用简洁性。
4.2类的实现
//RationalNumber.cpp文件,类实现
#include"stdafx.h"
#include"RationalCompute.h"
#include"RationalNumber.h"
//////////////////////////////////////////////////////////////////////
//Construction/Destruction
//////////////////////////////////////////////////////////////////////
CRationalNumber:
:
CRationalNumber(intnt,intdt)
//带有默参数构造函数的定义
{
inttemp,num,n,d;
n=nt;
d=dt;
if(n {temp=n; n=d; d=temp;} while(d! =0)//求分子和分母的最大公约数 {num=n%d; n=d; d=num; } numtor=nt/n; //构造函数以最简分数的形式存储数据 dentor=dt/n; } CRationalNumber: : ~CRationalNumber() { } CRationalNumberCRationalNumber: : operator+(CRationalNumber&rn)//加号运算符重载函数的定义 { CRationalNumbertemp; temp.numtor=this->numtor*rn.dentor+rn.numtor*this->dentor; temp.dentor=this->dentor*rn.dentor; inttemp1,num,n,d; n=temp.numtor; d=temp.dentor; if(n {temp1=n; n=d; d=temp1; } while(d! =0) {num=n%d; n=d; d=num; } temp.numtor=temp.numtor/n; temp.dentor=temp.dentor/n; return(temp); } CRationalNumberCRationalNumber: : operator-(CRationalNumber&rn)//减号运算符重载函数的定义 { CRationalNumbertemp; temp.numtor=this->numtor*rn.dentor-rn.numtor*this->dentor; temp.dentor=this->dentor*rn.dentor; inttemp1,num,n,d; n=temp.numtor; d=temp.dentor; if(n {temp1=n; n=d; d=temp1;} while(d! =0) {num=n%d; n=d; d=num; } temp.numtor=temp.numtor/n; temp.dentor=temp.dentor/n; return(temp); } CRationalNumberCRationalNumber: : operator*(CRationalNumber&rn)//乘号运算符重载函数的定义 { CRationalNumbertemp; temp.numtor=this->numtor*rn.numtor; temp.dentor=this->dentor*rn.dentor; inttemp1,num,n,d; n=temp.numtor; d=temp.dentor; if(n {temp1=n; n=d; d=temp1;} while(d! =0) {num=n%d; n=d; d=num; } temp.numtor=temp.numtor/n; temp.dentor=temp.dentor/n; return(temp); } CRationalNumberCRationalNumber: : operator/(CRationalNumber&rn)//除号运算符重载函数的定义 { CRationalNumbertemp; temp.numtor=this->numtor*rn.dentor; temp.dentor=this->dentor*rn.numtor; inttemp1,num,n,d; n=temp.numtor; d=temp.dentor; if(n {temp1=n; n=d; d=temp1;} while(d! =0) {num=n%d; n=d; d=num; } temp.numtor=temp.numtor/n; temp.dentor=temp.dentor/n; return(temp); } //将有理数转换成浮点数 floatCRationalNumber: : ConvertFloat() { //分母为0,返回-1。 表示错误。 if(dentor==0) return-1; floattemp; temp=float(this->numtor)/float(this->dentor); return(temp); } ostream&operator<<(ostream&output,RationalNumber&rn)//重载流插入运算符的定义,使分数以(a/b)形式输出 { if(rn.dentor==0)//分母是0输出error cout<<"error! "< else{ if(rn.numtor>0&&rn.dentor<0) output<<-rn.numtor<<"/"<<-rn.dentor; else output< returnoutput; } } 在类的构造函数中,对用户输入的数据进行了求最大公约数处理,使输入数据看起来最简洁化。 而且在所有的运算操作中都对错误的数据(如分母为0)的情况进行了处理。 由于运算符<<比较特殊,所以没有将<<重载符放入类的成员函数中,而是作为全局函数来处理,避免与cout<<的冲突。 4.3主函数设计 //main.cpp主函数 #include"RationalNumber.h" intmain() { cout<<".oO欢迎使用有理数计算器Oo.请根据提示输入运算数据! "< intn1,n2,m1,m2; cout<<"\n\n请输入第一个分数的分子与分母: "< cin>>n1>>n2; cout<<"请输入第二个分数的分子与分母: "< cin>>m1>>m2; RationalNumberrn1(n1,n2); //定义类的对象rn1并指定分子与分母值 RationalNumberrn2(m1,m2); //定义类的对象rn2并指定分子与分母值 RationalNumberrn3,rn4,rn5,rn6; //定义类的对象rn3,rn4,rn5,rn6不指定分子与分母,用默认参数对其初始化 //调用以浮点形式输出分数函数 rn3=rn1+rn2;//调用加号重载函数 rn4=rn1-rn2;//调用减号重载函数 rn5=rn1*rn2;//调用乘号重载函数 rn6=rn1/rn2;//调用除号重载函数 cout< "< //调用流插入运算符,使分数以(a/b)形式输出 rn3.showfloat(); //调用以浮点形式输出分数函数 cout< "< //调用流插入运算符,使分数以(a/b)形式输出 rn4.showfloat(); //调用以浮点形式输出分数函数 cout< "< //调用流插入运算符,使分数以(a/b)形式输出 rn5.showfloat(); //调用以浮点形式输出分数函数 cout< "< //调用流插入运算符,使分数以(a/b)形式输出 rn6.showfloat(); //调用以浮点形式输出分数函数 cout<<"--------计算完成,请按任意键退出系统! "< getchar(); getchar(); return0; } 在程序的主函数部分,选择了让用户输入操作数据的方式来互动,当用户根据提示来输入相应的数据后,程序会自动运算出每组数据的所有操作结果,如果用户输入数据有错误,则会显示出错误信息。 5DOS界面程序运行结果及分析 5.1程序运行结果 当输入正确无误的数据后,程序运行结果如图2所示。 图2程序运行结果 从图2中可以看出,当输入正确的数据后,系统能正确无误的计算出有理数相加,相减,相乘,相除的结果,并能正确转换成小数形式。 当输入有误的数据,如分母为0的时候,程序运行结果如图3所示。 图3程序运行结果(错误数据源) 从图3中可以看出,当输入错误的数据后,程序会检测出错误数据源,证明了程序的健壮性。 当输入的数据分子和分母最大公约数不为1的情况下,程序运行结果如图4所示: 图4程序运行结果(有公约数) 可以很清楚的看出来,系统已经将输入的2/4进行求最大公约数后,当成1/2来运算,证明设计中的最大公约数问题也得到了很好的解决。 5.2运行结果分析 首先当向程序输入正确的数据源后,程序能准确快速的计算出4则运算的结果,当向程序输入分母为0的错误的数据后,程序也同样能够识别。 当向程序中输入的分子分母有最大公约数,并且最大公约数不为1的情况下,说明分数可以化简,程序也能很好的识别并给出正确的结果。 从运行结果来分析,设计的有理数类完全满足于需求。 6基于MFC的图形界面程序开发 MFC的图形界面程序设计可在上述类设计的基础上进行改造,MFC的图形界面程序与DOS界面程序的主要不同点是: MFC图形界面程序与DOS界面程序的输入输出方式不同,DOS界面程序采用字符交互式实现数据输入输出,主要通过cin,cout等I/O流实现,而MFC的图形程序界面采用标准Windows窗口和控件实现输入输出,因此必须在MFC类的框架下加入上面所设计的矩阵和方程组类,并通过图形界面的输入输出改造来完成。 6.1基于MFC的图形界面程序设计 (1)界面设计 首先在VC中建立MFCAppWizard(exe)工程,名称为RationalCompute,并在向导的Step1中选择Dialogbased,即建立基于对话框的应用程序,如下图5~6所示。 图5建立MFCAppWizard(exe)工程 图6建立基于对话框的应用程序 将对话框资源中的默认对话框利用工具箱改造成如下界面,如图7所示。 图7有理数运算器程序界面设计 图6所示的界面中主要包含了7个StaticText控件,4个Button控件,和6个EditBox控件,控件的基本信息列表如下表1所示。 表1控件基本信息 控件类别 控件ID 控件Caption 说明 StaticText IDC_STATIC 分子 分母 Expression Botton IDC_BUTTON_ADD 加 进行加法运算 IDC_BUTTON_SUBTRACTION 减 进行减法运算 IDC_BUTTON_MULTIPLICATE 乘 进行乘法运算 IDC_BUTTON_DIVISION 除 进行除法运算 EditBox IDC_EDIT_FST_NUMTOR 第一个分数的分子 IDC_EDIT_FST_DENTOR 第一个分数的分母 IDC_EDIT_SND_NUMTOR 第二个分数的分子 IDC_EDIT_SND_DENTOR 第二个分数的分母 IDC_EDIT_RESULT_FRA 分数结果 IDC_EDIT_RESULT_FLOAT 小数结果 (2)代码设计 为了能够将对话框界面上的控件能够与代码联系起来,需要为主要的6个EditBox控件建立MemberVariables,按Ctrl+w键进入MFCClassWizard界面,选择MemberVariables选项卡,可显示成员变量设置界面,如图8所示。 图8成员变量设置界面 下面是编写代码的重要阶段,可以借鉴在设计基于DOS界面的控制台应用程序的代码,并将其作必要的改写,具体改写的步骤与内容如下。 1.将CRationalNumber类拷贝一份到新的MFC工程目录下。 2.去掉operator<<重载操作符函数,因为现在是MFC程序,所以不需要格式化输出到控制台,但会已其他形式出现。 3.修改成员函数,分数转变成小数的函数: //将有理数转换成浮点数 floatCRationalNumber: : ConvertFloat() { //分母为0,返回-1。 表示错误。 if(dentor==0) return-1; floattemp; temp=float(this->numtor)/float(this->dentor); return(temp); } 这里只需要转换成小数形式作为返回值就可以了。 4.封装函数checkInput。 来检查用户输入数据是否正确。 函数具体设计代码如下: intCRationalComputeDlg: : checkInput() { UpdateData(TRUE);//更新数据 if(0==m_nFstDentor) { AfxMessageBox("第一个分数的分母不能为0! "); ProCalError(); return-1; } if(0==m_nSndDentor) { AfxMessageBox("第二个分数的分母不能为0! "); ProCalError(); return-1; } return0; } 检查用户输入合法性,返回0表示输入合法,否则表示输入非法 5.封装新的函数ProCalError来处理运算错误。 具体代码如下: voidCRationalComputeDlg: : ProCalError() { m_strExpression="Error"; m_strResult=""; m_fResult=0.f; } 主要是将显示结果滞空,告诉用户
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 分数 设计 实现 有理数 运算