大整数乘法问题Word格式文档下载.docx
《大整数乘法问题Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《大整数乘法问题Word格式文档下载.docx(16页珍藏版)》请在冰豆网上搜索。
![大整数乘法问题Word格式文档下载.docx](https://file1.bdocx.com/fileroot1/2022-12/29/5d86c4b4-9117-442e-8c91-11c3fceab927/5d86c4b4-9117-442e-8c91-11c3fceab9271.gif)
当大整数需要进行分治乘法时,在两个乘数的高位补0,使它们的位数达到相同的2的次幂;
分治结束后,将得到的乘积的高位多余的0去除,进行加减等非分治算法运算;
以此类推。
采用这种高位补0的位数处理方法,实现了任意位大整数的乘法。
除了上述三点之外,程序对鲁棒性做了增强,对非法输入和文件错误进行了检测。
程序设计代码:
/*头文件大数乘法问题.h*/
#ifndefKNAP_H
#defineKNAP_H
#include<
iostream>
fstream>
string>
usingnamespacestd;
/*定义数制,范围2到10*/
#defineSCALE10
/*整数的最大位数*/
constintMax=1000;
/*表示整数的结构体*/
structInteger
{
boolpositive;
//整数的正负
shortnum[Max];
//整数的各位数字,下标从0开始
intlength;
//整数的位数
};
/*两个整数的乘法类*/
classMultiply
public:
Multiply(char*in,char*out);
//构造函数
~Multiply();
//析构函数
voidOutputProduct();
//输出大整数的乘积
protected:
shortCharToInt(charch);
//将数字字符转化成整型
intAddDigit(Integer&
X,Integer&
Y);
//将位数补充到相同2的次幂位
voidInitialInteger(Integer&
integer,ifstream&
in);
//文件初始化大整数
voidOutputInteger(Integerinteger);
//输出大整数integer
voidClearZero(Integer&
integer);
//去除大整数高位多余的0
boolPositiveXGreaterThanY(IntegerX,IntegerY);
//判断是否非负X大于非负Y
boolEqualsToZero(Integerinteger);
//判断是否等于0
IntegerZero();
//返回大整数0
IntegerGetAbsolute(Integerinteger);
//返回大整数integer的绝对值
IntegerGetNegative(Integerinteger);
//返回大整数integer的负值
IntegerGetLeft(Integerinteger);
//取大整数integer左一半
IntegerGetRight(Integerinteger);
//取大整数integer右一半
IntegerLeftShifting(Integerinteger,intdigit);
//大整数向左移digit位,低位补0
IntegerPlus(IntegerX,IntegerY);
//大整数加法
IntegerSubtract(IntegerX,IntegerY);
//大整数减法
IntegerSameSignPlus(IntegerX,IntegerY);
//同号大整数加法
IntegerSameSignSubtract(IntegerX,IntegerY);
//同号大整数减法
IntegerOneDigitMultiply(IntegerX,IntegerY);
//非负1位大整数乘法
IntegerFreeMultiply(IntegerX,IntegerY);
//任意大整数乘法
IntegerNDigitsMultiply(IntegerX,IntegerY,intn);
//2的n次幂乘法,高位补0
private:
Integerinteger_X,integer_Y;
//数组存储的大整数
ofstreamfout;
//输出结果文件
#endif
/*函数实现文件大数乘法问题.cpp*/
#include"
大数乘法问题.h"
Multiply:
:
Multiply(char*in,char*out):
fout(out)
try//非法输入检测
{
ifstreamfin(in);
if(!
fin)
throw"
输入文件无法打开!
\n"
;
InitialInteger(integer_X,fin);
//文件初始化大整数integer_X
fin.ignore(100,'
\n'
);
//冲掉回车
InitialInteger(integer_Y,fin);
//文件初始化大整数integer_Y
fin.close();
//关闭文件
fout)
输出文件无法打开!
}
catch(char*string)
cout<
<
string;
system("
pause"
exit(0);
}
~Multiply()
if(fout)
fout.close();
voidMultiply:
OutputProduct()
Integertemp=FreeMultiply(integer_X,integer_Y);
ClearZero(temp);
OutputInteger(temp);
shortMultiply:
CharToInt(charch)
shorttemp;
switch(ch)
case'
0'
:
temp=0;
break;
1'
temp=1;
2'
temp=2;
3'
temp=3;
4'
temp=4;
5'
temp=5;
6'
temp=6;
7'
temp=7;
8'
temp=8;
9'
temp=9;
default:
temp=-1;
if(temp==-1)
throw"
Error:
输入存在非数字字符!
if(temp>
=SCALE)
输入不符合数制!
returntemp;
intMultiply:
AddDigit(Integer&
Y)
intdigit=0;
if(X.length>
Y.length)
digit=X.length;
else
digit=Y.length;
//取二者最大位数
inti;
for(i=0;
pow(2.0,i)<
digit;
i++);
digit=(int)pow(2.0,i);
//取满足二者的最小2的次幂
for(i=digit-1;
i>
=X.length;
i--)
X.num[i]=0;
=Y.length;
Y.num[i]=0;
//高位补0,使位数达到2的次幂
X.length=Y.length=digit;
//改变二者的位数
returndigit;
//返回2的次幂
InitialInteger(Integer&
in)
if(in.peek()=='
-'
)
in.get();
integer.positive=false;
integer.positive=true;
chartemp[Max];
in.peek()!
='
&
&
!
in.eof();
i++)//读到回车处或文件结束
in>
>
temp[i];
integer.length=i;
i<
integer.length;
i++)
integer.num[i]=CharToInt(temp[integer.length-i-1]);
//将每一位字符转化为整型
OutputInteger(Integerinteger)
if(integer.length==0)//结果为0
fout<
integer.num[0];
if(integer.positive==false)//结果为负数
fout<
'
for(inti=integer.length-1;
-1;
integer.num[i];
ClearZero(Integer&
integer)
for(inti=integer.length-1;
integer.num[i]==0&
=0;
integer.length--;
boolMultiply:
PositiveXGreaterThanY(IntegerX,IntegerY)
Y.length)//X位数大于Y
returntrue;
elseif(X.length<
Y.length)//X位数小于Y
returnfalse;
for(inti=X.length-1;
i--)//从高位逐位比较
if(X.num[i]>
Y.num[i])//某一位X大于Y
returntrue;
elseif(X.num[i]<
Y.num[i])//某一位X小于Y
returnfalse;
returntrue;
//X=Y返回true
EqualsToZero(Integerinteger)
if(integer.num[i]!
=0)
returnfalse;
IntegerMultiply:
Zero()
Integertemp;
temp.length=0;
//0的位数定义为0
temp.positive=true;
temp.num[0]=0;
//0的第一位默认为0
GetAbsolute(Integerinteger)
if(integer.positive==false)
returninteger;
GetNegative(Integerinteger)
if(integer.positive==true)
GetLeft(Integerinteger)
temp.length=integer.length/2;
//位数为一半
//默认是正数
for(inti=0;
temp.length;
i++)//取原整数左一半
temp.num[i]=integer.num[i+temp.length];
//去除高位多余的0
GetRight(Integerinteger)
i++)//取原整数右一半
temp.num[i]=integer.num[i];
LeftShifting(Integerinteger,intdigit)
if(!
EqualsToZero(integer))
for(inti=integer.length+digit-1;
=digit-1;
integer.num[i]=integer.num[i-digit];
//原有位向高位移digit位
for(inti=digit-1;
integer.num[i]=0;
//低位补0
integer.length=integer.length+digit;
//位数加digit
Plus(IntegerX,IntegerY)
if(X.positive==Y.positive)//同号
returnSameSignPlus(X,Y);
else//异号
if(X.positive)//X正Y负
{
Y=GetNegative(Y);
//Y取负得正
returnSameSignSubtract(X,Y);
}
else//Y正X负
X=GetNegative(X);
//X取负得正
returnSameSignSubtract(Y,X);
Subtract(IntegerX,IntegerY)
returnSameSignSubtract(X,Y);
Y=GetNegative(Y);
//Y取负得正
SameSignPlus(IntegerX,IntegerY)
intcarry_flag=0;
//进位
X.length&
Y.length;
if(X.num[i]+Y.num[i]+carry_flag>
SCALE-1)//当为加法需要进位
X.num[i]=(X.num[i]+Y.num[i]+carry_flag)%SCALE;
carry_flag=1;
else
X.num[i]=X.num[i]+Y.num[i]+carry_flag;
carry_flag=0;
if(i<
X.length)//被加数位数大于加数
while(i<
X.length)
if(X.num[i]+carry_flag>
SCALE-1)//需要进位
{
X.num[i++]=(X.num[i]+carry_flag)%SCALE;
carry_flag=1;
}
else
X.num[i++]=X.num[i]+carry_flag;
carry_flag=0;
elseif(i<
Y.length)//加数位数大于被加数
if(Y.num[i]+carry_flag>
X.num[i++]=(Y.num[i]+carry_flag)%SCALE;
X.num[i++]=Y.num[i]+carry_flag;
if(carry_flag==1)//最高位存在进位
X.num[i]=1;
X.length=i+1;
X.length=i;
returnX;
SameSignSubtract(IntegerX,IntegerY)
if(PositiveXGreaterThanY(X,Y))//如果绝对值X>
=Y
inti;
intcarry_flag=0;
//借位
boolfirst_0=true;
//高位第一次出现0
inttop_digit_0=0;
//记录结果最高位+1的下标
inttop_digit=0;
//记录结果最高位下标
for(i=0;
if(X.num[i]-carry_flag<
Y.num[i])//需要向高位借位
X.num[i]=(X.num[i]-carry_flag+SCALE-Y.num[i]);
X.num[i]=X.num[i]-carry_flag-Y.num[i];
if(X.num[i]==0)//高位出现0
if(first_0)//且是第一次出现0
{
first_0=false;
//再出现0则不是第一次出现0
top_digit_0=i;
//记录结果最高位+1的下标
}
first_0=true;
top_digit=i;
if(carry_flag==1)//最高位存在借位
X.num[i]=X.num[i]-carry_flag;
if(X.num[i]==0&
firs