高精度乘法和加法

前两天,我在学习数据结构的时候,有朋友问我“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的阶乘也就方便了,这才是最后的递归!!

各位,请多指教!

posted @ 2005-07-22 10:33  西就东城  阅读(3185)  评论(3编辑  收藏  举报