大整数基本运算的实现研究与分析.docx
《大整数基本运算的实现研究与分析.docx》由会员分享,可在线阅读,更多相关《大整数基本运算的实现研究与分析.docx(36页珍藏版)》请在冰豆网上搜索。
大整数基本运算的实现研究与分析
5设计核心代码…………………………………………………......3
9设计体会..................................................................................9
10源代码………………………………………………………………………………….10
一、设计要求
1.实现大整数(128位)的基本运算、如加、减、乘、除运算;
2.实现大整数的存取;
3.界面简洁、交互操作性强。
二、开发环境与工具
Windows8.1、visualstudio2012
3、设计原理(算法工作原理)
大整数的概念“大整数”一般指位数达到十几或成百上千甚至更多的整数,而更准确地说,应该是指普通程序设计语言中的整数类型值集范围以上的整数。
如标准的C的Unsignedlong型整数所能处理的整数范围最大,有效数位也最多,为4294967295(
)占据32位(4个字节)存贮空间,此时,大整数就是指十位以上的十进制整数了。
“大整数”运算是指“大整数”之间的加减乘除等运算结果依然保持其数学理论上准确和精确的结果。
我们采用数组存储的方式存储,并且存储的位数不能大于256位,否则会发生溢出错误而导致大整数处理错误。
对于负数,程序将不能处理,可以输入,计算结果输出为整数。
4、系统功能描述与软件模块划分
相关函数介绍
voidhadd(int*xx1,int*xx2,int*xx3,intxn1,intxn2,int&xn3)/*加法操作*/
voidhsub(int*xx1,int*xx2,int*xx3,intxn1,intxn2,int&xn3)/*减法操作*/
voidhmul(int*xx1,int*xx2,intxn1,int&xn2,intxn)/*乘法操作*/
inthdiv(int*xx1,int*xx2,int*xx3,intxn1,intxn2,int&xn3)/*除法操作*/
voidshow(int);//显示
5、设计核心代码
1、加法
在大整数四则运算中,加法是基本的运算,也最容易实现。
voidhadd(int*xx1,int*xx2,int*xx3,intxn1,intxn2,int&xn3)/////////////////////////////////*加法操作*/
{
inti,j,k=0;
if(xn1>xn2)
{
xn3=xn1;//xn3为过渡位,都表示最大位数
for(i=0;ixx2[Max-xn3+i]=0;//对小数xx2高位填充0,直至位数相等
}
else
{
xn3=xn2;
for(i=0;ixx1[Max-xn3+i]=0;/*把短的字符串前补0*/
}
for(i=0;i{
j=xx1[Max-1-i]+xx2[Max-1-i]+k;//从数组空间的最高位开始加,最右边
k=j/10;/*表示进位*/
xx3[Max-1-i]=j%10;//值的最右边开始,填满结果
}
if(k&&(Max-xn3>=1))//有进位且结果未满256
{
xx3[Max-1-xn3]=k;//将结果填满
xn3++;
}/*增加一位存放最高位*/
}
voidlarnum:
:
add(void)
{
hadd(x1,x2,x3,n1,n2,n3);
}
2、减法
voidhsub(int*xx1,int*xx2,int*xx3,intxn1,intxn2,int&xn3)////////////////////////*减法操作*/
{
inti,j,k=0;
xn3=xn1;//将被减数位数付给结果的位数
for(i=0;ixx2[Max-xn3+i]=0;//将减数的高位用0从左到右补齐
for(i=0;i{
j=xx1[Max-1-i]-xx2[Max-1-i]-k;//从右往左开始减法
if(j>=0)
{
k=0;//不进位,减下来的值就给xx3
xx3[Max-1-i]=j;
}
else
{
k=1;//否则进一位,左边的高位加上10
xx3[Max-1-i]=j+10;
}
}
for(i=0;ixn3-=i;
}
voidlarnum:
:
sub(void)
{
hsub(x1,x2,x3,n1,n2,n3);
}
3、乘法
voidhmul(int*xx1,int*xx2,intxn1,int&xn2,intxn)////////////////////////////////////////*乘法操作*/
{
inti,j,k=0;
for(i=0;i{
j=xx1[Max-1-i]*xn+k;//从低位开始相乘,满10进1
k=j/10;
xx2[Max-1-i]=j%10;//xx2表示相乘的结果-n*10后的值
}
xn2=xn1;//将乘法的多位的位数值赋值给结果的位数
if(k&&(Max-xn2>=1))//有进位且结果的位数无溢出
{
xx2[Max-1-xn2]=k;//从低位将结果补满
xn2++;
}
for(i=0;ixn2-=i;
}
voidlarnum:
:
mul(void)//larnum的成员mul(),进行乘法运算
{
inti,j,k,x[Max],xn,y[Max],yn=0;
for(i=0;i{
hmul(x1,x,n1,xn,x2[Max-1-i]);//调用私有成员函数hmul()xn为结果的长度
for(j=0;j=1);j++)//因为是大整数相乘,会有多次的两数相乘乘积得到的值
{
for(k=0;kx[Max-1-xn+k]=x[Max-xn+k];
x[Max-1]=0;
xn++;
}
hadd(x,y,x3,xn,yn,n3);
for(j=0;jy[Max-1-j]=x3[Max-1-j];//多次的两数相乘乘积得到的值进行加法运算
yn=n3;
}
for(i=0;in3-=i;
}
4、除法
inthdiv(int*xx1,int*xx2,int*xx3,intxn1,intxn2,int&xn3)//////////////////////////////////////*除法操作*/
{
inti,k;
if(xn1>xn2)//被除数>除数的情况
k=0;//k==0
elseif(xn1==xn2)
{
for(i=0,k=2;i{
if(xx1[Max-xn1+i]>xx2[Max-xn1+i])//比较同长度的数最高位,标志位为0不变,正常的除法情况
{
k=0;
break;
}
elseif(xx1[Max-xn1+i]{
k=1;
break;
}
}
}
elsek=1;
if(k==1)//如果是同长高位1<2,或者长度1<长度256/666/66
{
for(i=0;ixx3[Max-1-i]=xx1[Max-1-i];//从低位开始,将1的数值赋给xx3,作为余数
xn3=xn1;//将小的被除数的长度赋给余数
}
if(k==2)
{
xx3[Max-1]=0;//两数同长且相等的情况,余数为0,长度为1
xn3=1;
}
if(k==0)//两数相等且最高位1>26?
?
/5?
?
hsub(xx1,xx2,xx3,xn1,xn2,xn3);//调用上面的hsub函数,此时就相当于减法操作了,因为商唯一,得出余数
returnk;
}
}
intlarnum:
:
div(void)
{
intx[Max],xn=0,i,j,k,n;
if(n2==0||(n2==1&&x2[Max-1]==0))//判断输入的数是否合法,除数为0报错
{
cout<<"error.除数不能为0!
"<return1;
}
for(i=0,n3=n1;i{
for(j=0;jx[Max-1-xn+j]=x[Max-xn+j];
x[Max-1]=x1[Max-n1+i];
xn++;
k=hdiv(x,x2,x4,xn,n2,n4);
if(k==2)
x3[Max-n1+i]=1;
elseif(k==1)
x3[Max-n1+i]=0;
else
{
for(n=1;;n++)
{
for(j=0;jx[Max-1-j]=x4[Max-1-j];
xn=n4;
k=hdiv(x,x2,x4,xn,n2,n4);
if(k==1)
break;
}
x3[Max-n1+i]=n;
}
for(j=0;jx[Max-1-j]=x4[Max-1-j];//长度也进行赋值
xn=n4;
}
for(i=0;in3-=i;
for(i=0;in4-=i;
return0;
}
六、设计结果及验证
以下是我本次设计软件的使用,以及使用成功的截图。
7、软件使用说明
选择一,然后输入两个大整数,进行加法运算,结果如下:
选择二,然后输入两个大整数,进行减法运算,结果如下:
选择三,然后输入两个大整数,进行乘法运算,结果如下:
选择四,然后输入两个大整数,进行除法运算,结果如下:
#include
#include
usingnamespacestd;
#defineMax256/*定义数组大小为256,以至能实现128位大整数的乘法*/
classlarnum
{
public:
voidadd(void);
voidsub(void);
voidmul(void);
intdiv(void);
larnum(char*,char*);
voidshow(int);
private:
intx1[Max];
intx2[Max];
intx3[Max];
intx4[Max];
intn1;
intn2;
intn3;
intn4;
voidhadd(int*xx1,int*xx2,int*xx3,intxn1,intxn2,int&xn3)/////////////////////////////////*加法操作*/
{
inti,j,k=0;
if(xn1>xn2)
{
xn3=xn1;//xn3为过渡位,都表示最大位数
for(i=0;ixx2[Max-xn3+i]=0;//对小数xx2高位填充0,直至位数相等
}
else
{
xn3=xn2;
for(i=0;ixx1[Max-xn3+i]=0;/*把短的字符串前补0*/
}
for(i=0;i{
j=xx1[Max-1-i]+xx2[Max-1-i]+k;//从数组空间的最高位开始加,最右边
k=j/10;/*表示进位*/
xx3[Max-1-i]=j%10;//值的最右边开始,填满结果
}
if(k&&(Max-xn3>=1))//有进位且结果未满256
{
xx3[Max-1-xn3]=k;//将结果填满
xn3++;
}/*增加一位存放最高位*/
}
voidhsub(int*xx1,int*xx2,int*xx3,intxn1,intxn2,int&xn3)////////////////////////*减法操作*/
{
inti,j,k=0;
xn3=xn1;//将被减数位数付给结果的位数
for(i=0;ixx2[Max-xn3+i]=0;//将减数的高位用0从左到右补齐
for(i=0;i{
j=xx1[Max-1-i]-xx2[Max-1-i]-k;//从右往左开始减法
if(j>=0)
{
k=0;//不进位,减下来的值就给xx3
xx3[Max-1-i]=j;
}
else
{
k=1;//否则进一位,左边的高位加上10
xx3[Max-1-i]=j+10;
}
}
for(i=0;ixn3-=i;
}
voidhmul(int*xx1,int*xx2,intxn1,int&xn2,intxn)////////////////////////////////////////*乘法操作*/
{
inti,j,k=0;
for(i=0;i{
j=xx1[Max-1-i]*xn+k;//从低位开始相乘,满10进1
k=j/10;
xx2[Max-1-i]=j%10;//xx2表示相乘的结果-n*10后的值
}
xn2=xn1;//将乘法的多位的位数值赋值给结果的位数
if(k&&(Max-xn2>=1))//有进位且结果的位数无溢出
{
xx2[Max-1-xn2]=k;//从低位将结果补满
xn2++;
}
for(i=0;ixn2-=i;
}
inthdiv(int*xx1,int*xx2,int*xx3,intxn1,intxn2,int&xn3)//////////////////////////////////////*除法操作*/
{
inti,k;
if(xn1>xn2)//被除数>除数的情况
k=0;//k==0
elseif(xn1==xn2)
{
for(i=0,k=2;i{
if(xx1[Max-xn1+i]>xx2[Max-xn1+i])//比较同长度的数最高位,标志位为0不变,正常的除法情况
{
k=0;
break;
}
elseif(xx1[Max-xn1+i]{
k=1;
break;
}
}
}
elsek=1;
if(k==1)//如果是同长高位1<2,或者长度1<长度256/666/66
{
for(i=0;ixx3[Max-1-i]=xx1[Max-1-i];//从低位开始,将1的数值赋给xx3,作为余数
xn3=xn1;//将小的被除数的长度赋给余数
}
if(k==2)
{
xx3[Max-1]=0;//两数同长且相等的情况,余数为0,长度为1
xn3=1;
}
if(k==0)//两数相等且最高位1>26?
?
/5?
?
hsub(xx1,xx2,xx3,xn1,xn2,xn3);//调用上面的hsub函数,此时就相当于减法操作了,因为商唯一,得出余数
returnk;
}
};
larnum:
:
larnum(char*y1="0",char*y2="0")
{
inti;
for(n1=0;n1='0'&&y1[n1]<='9';n1++);//用n1表示输入的第一个数满足在0---9之间,就接受
for(i=0;ix1[Max-n1+i]=*(y1+i)-48;
for(i=0;in1-=i;
for(n2=0;n2='0'&&y2[n2]<='9';n2++);//用n2表示输入的第一个数满足在0---9之间,就接受
for(i=0;ix2[Max-n2+i]=*(y2+i)-48;
for(i=0;in2-=i;
}
//////////////////////////////////////////////////////////////////////////////
voidlarnum:
:
add(void)//larnum的成员add(),加法直接调用加法hadd()
{
hadd(x1,x2,x3,n1,n2,n3);
}
voidlarnum:
:
sub(void)//larnum的成员sub(),减法直接调用减法hsub()
{
hsub(x1,x2,x3,n1,n2,n3);
}
//////////////////////////////////////////////////////////////////////////
voidlarnum:
:
mul(void)//larnum的成员mul(),进行乘法运算
{
inti,j,k,x[Max],xn,y[Max],yn=0;
for(i=0;i{
hmul(x1,x,n1,xn,x2[Max-1-i]);//调用私有成员函数hmul()xn为结果的长度
for(j=0;j=1);j++)//因为是大整数相乘,会有多次的两数相乘乘积得到的值
{
for(k=0;kx[Max-1-xn+k]=x[Max-xn+k];
x[Max-1]=0;
xn++;
}
hadd(x,y,x3,xn,yn,n3);
for(j=0;jy[Max-1-j]=x3[Max-1-j];//多次的两数相乘乘积得到的值进行加法运算
yn=n3;
}
for(i=0;in3-=i;
}
/////////////////////////////////////////////////////////////
intlarnum:
:
div(void)
{
intx[Max],xn=0,i,j,k,n;
if(n2==0||(n2==1&&x2[Max-1]==0))//判断输入的数是否合法,除数为0报错
{
cout<<"error.除数不能为0!
"<return1;
}
for(i=0,n3=n1;i{
for(j=0;jx[Max-1-xn+j]=x[Max-xn+j];
x[Max-1]=x1[Max-n1+i];
xn++;
k=hdiv(x,x2,x4,xn,n2,n4);
if(k==2)
x3[