• 高精度乘法和加法


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

    各位,请多指教!

  • 相关阅读:
    MongoDB学习笔记(一:常见问题汇总)
    设计模式学习笔记(三:装饰模式)
    设计模式学习笔记(二:观察者模式)
    设计模式学习笔记(一:命令模式)
    Java基础知识笔记(七:接口、变量作用域和参数传递)
    Java基础知识笔记(六:网络程序设计)
    一周总结汇总_2016-09-25
    开涛spring3(8.1)
    开涛spring3(7.5)
    开涛spring3(7.4)
  • 原文地址:https://www.cnblogs.com/GoGoagg/p/197862.html
Copyright © 2020-2023  润新知