Java常用数字工具类大数乘法,加法,减法运算(2)

  

上篇分享了一下数字转汉字的小功能,这里再分享一下大数相乘,相加,相减的功能。其他的不做过多的铺垫了,我先讲一下各个功能的计算原理。

  

<强>Ⅰ。乘法运算
  

  

为什么先说乘法运算,因为我先做了乘法运算。其实思路也是很多的,但是最终我参考了网络上的一种计算方案,然后做了很多的修改。感觉这个在思路上应该是比较简单的。
  

  

简单点说:把数拆分成整数小数分别进行乘法运算,然后将结果放入一个特定长度的数组中,在放入是要计算存放的偏移位置,最后再对这个进行处理(进位,标记等),得到最终的结果。
  是不是有点晕。请我详细说一下吧:
  

  
      <李>首先还得把数都拆成整数+小数,然后采用的是(x1 + x2) (y1 + y2)=x + x1y2 + x2y1 + x。这种方式来计算的,这样来算,都变成了整数的运算了。要简单很多。但是4个结果怎么累加起来计算呢,这就是第二步。
      李   <李>要申明一个int数组,长度=整数长度和+小数长度和+ 1(小数点占1位)。通过实验,我们可以看到任意2个整数相乘结果都不会超过这两个数的长度和。
      李   <李>人为计算乘法的时候就是按右向左一位一位的计算的(低位对齐),所以为了对齐低位,我们将整数和小数全部反转,并且转化为字符数组,方便运算。然后进行4次乘法。
      李   <李>按位进行乘法运算,采用双层为循环完成这个操作。这里最为天才的想法就是——不进位。当然必须得弄清楚整数相乘放在数组的哪些个位置,小数相乘存放的开始位置,以及整数和小数相乘结果存放的开始位置。
      李   <李>处理结果集合,将祝辞=10的做进位处理。
      李   <李>这一步也是很有才的想法,对小数点位置进行标记,而不是直接替换成”。”(int数组也不能直接设定(/鮘))。
      李   <李>有了第6步的想法,就有了第7步的做法,处理整数部分头部的0和小数部分末尾的0,都是无效数字,这里同样采用标记的方式来处理
      李   <李>最后将结果集合进行反转输出,遇到小数点标记和无效0标记直接替换和跳过。   
  

这就是基本的思路了。后面又再次基础上加上了负数的判断,数字格式的判断等,自己看注释就可以明白了。
  代码如下:
  

     //标记为小数点   私有静态最终int点=-99;//标记为无效数字   私有静态最终int无效=-100;/* *   *大数乘法   *   * @param第一个数   * @param b第二个数   * @return最终结果   */公共静态字符串相乘(字符串,字符串b) {//检查数字格式   checkNum(一个);   checkNum (b);//标记最终结果是否为负的值   布尔-=false;//判断是否有带着-号   如果(a.startsWith (“-”) | | b.startsWith (“-”)) {//判断是否全带着-号   如果(a.startsWith (“-”),,b.startsWith (“-”)) {   其他}{//只有1个带着号,则结果为负的值   -=true;   }   如果(a.startsWith (“-”)) {   一个=a.substring (1);   }   如果(b.startsWith (“-”)) {   b=b.substring (1);   }   }//获取a、b的整数和小数部分   字符串a_int=getInt ();   字符串a_fraction=getFraction(一个);   字符串b_int=getInt (b);   字符串b_fraction=getFraction (b);//计算小数部分的总长度   int len_fraction=a_fraction.length () + b_fraction.length ();//a、b两个数乘积的最大位数不会超过总位数之和+小数点(1位)   int len=len_fraction + a_int.length b_int.length () + () + 1;//创建结果数组   int[]结果=new int (len);//默认全为0//为了方便计算,去掉小数点(最后在结果中加上小数点)//并将高低位对调(反转是为了低位对齐),最终转化为字符数组   char [] s_a_int=reverseStr (a_int);   char [] s_a_fraction=reverseStr (a_fraction);   char [] s_b_int=reverseStr (b_int);   char [] s_b_fraction=reverseStr (b_fraction);//将a、b都拆分成整数+小数,然后//采用(x1 + x2) (y1 + y2)=x + x1y2 + x2y1 + x公式,分别计算乘积   乘(s_a_int s_b_int len_fraction,结果);   乘(s_a_int s_b_fraction (len_fraction-s_b_fraction.length),结果);   乘(s_b_int s_a_fraction (len_fraction-s_a_fraction.length),结果);   乘(s_a_fraction s_b_fraction 0,结果);//处理结果集合,如果是大于10的就向前一位进位,本身进行除10取余   accumulateResultArrays(结果);//标记小数点位置   markDot (len_fraction,结果);//切掉无用的0   cutUnusedZero (len_fraction,结果);//然后将数据反转   返回(- # 63;“-”:" ")+ reverseResult(结果);   }/* *   *反转字符串,并转化为数组   *   * @param年代原字符串   * @return   */私有静态char [] reverseStr (String s) {   返回新StringBuffer (s) .reverse () .toString () .toCharArray ();   }/* *   *计算2个数的每一位的乘积,放入到对应的结果数组中(未进位)   *   * @param第一个数   * @param b第二个数   * @param开始开始放入的偏移位置   * @param结果结果数组   */私有静态孔隙乘(char [], char [] b, int, int[]结果){//计算结果集合   for (int i=0;我& lt;a.length;我+ +){   for (int j=0;j & lt;b.length;j + +) {   结果(我+ j +) +=(int)([我],' 0 ')* (int) (b [j], ' 0 ');   }   }   }/* *   *累加每一位,超过10则然后进位   *   * @param结果结果数组   */私有静态孔隙accumulateResultArrays (int[]结果){   for (int i=0;我& lt;result.length;我+ +){   如果结果[我]祝辞=10){   结果(i + 1)(我)/10 +=结果;   结果[我]%=10;   }   }   }/* *   *标记小数点位置   *   * @param len_fraction小数长度   * @param结果结果数组(反转的)   */私有静态孔隙markDot (int len_fraction, int[]结果){   如果(len_fraction> 0) {//标记小数点位置   for (int i=结果。长度是1;我在;len_fraction;我(){   结果[我]=结果(张);   }   结果[len_fraction]=点;//标记小数点位置   }   }/* *   *去掉不必要的0(包括整数最前面的和小数最后面的0)   *   * @param len_fraction小数长度   * @param结果结果数组   */私有静态孔隙cutUnusedZero (int len_fraction, int[]结果){//去掉小数部分不必要的0   布尔flag_0_fraction=true;//标记一直是0   for (int i=0;i

Java常用数字工具类大数乘法,加法,减法运算(2)