前两天,我在学习数据结构的时候,有朋友问我“1000的阶乘怎么编程?”,我也没有想什么,答:“递归”。当我自己递归的时候,才发现电脑存储长度不够,得出的结果是一个科学计数法的数字。这样我就在网上查询资料,发现“高精度算法”这个概念(我真的感到世界太大了)。这里,我用算法思想写了一个。
为了更好实现乘法运算,我先编写了高精度加法运算。
private string GetLongADD(string num,string desnum)
{
//l1 被加数长度
//l2 加数长度
//upnum 进位数
int l1,l2,upnum;
string tempi;
l1=num.Length;
l2=desnum.Length;
upnum=0;
string Addnum="";
//被加数长度小于或等于加数长度,运行程序;反之,对调这两数的关系
if(l1<=l2)
{
//循环从个位开始,直到被加数每一位数据加完为止
for(int i=0;i<l1;i++)
{
//关键:
//在数字中,高位在左边;在字符串下标中,高位在右边;所以在对应数字位的时候,采用了{String.Length-1-循环位}
int ti=Convert.ToInt16(num[l1-1-i].ToString())+Convert.ToInt16(desnum[l2-1-i].ToString())+upnum;
Addnum=(ti.ToString().Substring(ti.ToString().Length-1,1)).ToString()+Addnum;
if(ti>9)
upnum=1;
else
upnum=0;
}
//当被加数长度等于加数长度,那么他们的高位数默认为0;反之,他们高位数是加数余下没有运算的数字
if(l1!=l2)
tempi=(desnum.Substring(0,l2-l1));
else
tempi="0";
//如果在循环被加数长度的对位相加后,高位进位为1,说明需要进1相加
if(upnum==1)
{
tempi=GetLongADD(tempi,"1");
}
//如果高位相加还是0,说明他们没有高位数据而且没有进位数据
if(tempi!="0")
Addnum=tempi.ToString()+Addnum;
}
else
{
Addnum=GetLongADD(desnum,num);
}
return Addnum;
}
高精度乘法:
private string AdvJS(string BSS,string SS)
{
int l1,l2,v1,v2;
l1=BSS.Length; //被乘数长度
l2=SS.Length; //乘数长度
string temp="0";
//分组进行乘法
v1=GetInt(l1,4); //求分组数
v2=GetInt(l2,4);
//定义分组数组----Begin
//举例:123456789,分组数组{'6789','2345','1'}
int[] bss=new int[v1];
int[] ss=new int[v2];
for(int i=0;i<v1;i++)
{
if(i==v1-1)
{
bss[i]=Convert.ToInt32(BSS.Substring(4*(v1-1-i),l1-4*(v1-1)));
}
else
{
int kk=l1-4*(v1-1);
bss[i]=Convert.ToInt32(BSS.Substring(4*(v1-2-i)+kk,4));
}
}
for(int i=0;i<v2;i++)
{
if(i==v2-1)
{
ss[i]=Convert.ToInt32(SS.Substring(4*(v2-1-i),l2-4*(v2-1)));
}
else
{
int kk=l2-4*(v2-1);
ss[i]=Convert.ToInt32(SS.Substring(4*(v2-2-i)+kk,4));
}
}
//定义分组数组----End
//利用高精度加法来实现高精度乘法,注意倍数
for(int i=0;i<v1;i++)
for(int j=0;j<v2;j++)
{
int tempi=(bss[i]*ss[j]);
int ki=4*i+4*j;
string ts;
if(ki>0)
ts="0".PadRight(ki,'0');//这就是倍数,其实就是n个'0'
else
ts="";
temp=GetLongADD(temp,tempi.ToString()+ts);
}
return temp;
}
//求倍数。比如:5/2=2.5,他的倍数是3;这里没有四舍五入的概念
private int GetInt(int l,int modnum)
{
if(l%modnum==0)
{
return l/modnum;
}
else
{
return (int)(l/modnum)+1;
}
}
那么,实现了高精度乘法和加法,实现1000的阶乘也就方便了,这才是最后的递归!!
各位,请多指教!