大数
BigInteger 
底层维护两个变量
BigInteger.java 1 2 3 4 5 public  class  BigInteger  extends  Number  implements  Comparable <BigInteger >     final  int  signum;     final  int [] mag;      } 
无符号整数 
BigInteger单独维护符号,因此数组每位都当做无符号数,即相当于最大无符号数作为进制
BigInteger.java 1 final  static  long  LONG_MASK = 0xffffffffL ;
实现中用int与掩码进行与操作,结果转成long,数值上和无符整数一致
Sample 1 2 3 int  a = 0x80000001 ;  long  b = a;  long  c = a & 0xffffffffL ;  
合并两个数组
BigInteger.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 private  static  int [] add(int [] x, int [] y) {         if  (x.length < y.length) {         int [] tmp = x;         x = y;         y = tmp;     }     int  xIndex = x.length;     int  yIndex = y.length;          int  result[] = new  int [xIndex];          long  sum = 0 ;     if  (yIndex == 1 ) {         sum = (x[--xIndex] & LONG_MASK) + (y[0 ] & LONG_MASK) ;         result[xIndex] = (int )sum;     } else  {                  while  (yIndex > 0 ) {             sum = (x[--xIndex] & LONG_MASK) + (y[--yIndex] & LONG_MASK) + (sum >>> 32 );                          result[xIndex] = (int )sum;         }     }          boolean  carry = (sum >>> 32  != 0 );     while  (xIndex > 0  && carry)         carry = ((result[--xIndex] = x[xIndex] + 1 ) == 0 );          while  (xIndex > 0 )         result[--xIndex] = x[xIndex];          if  (carry) {         int  bigger[] = new  int [result.length + 1 ];         System.arraycopy(result, 0 , bigger, 1 , result.length);         bigger[0 ] = 0x01 ;         return  bigger;     }     return  result; } 
不可变 
BigInteger是不可变的,所有操作都会返回新的对象
加减法 
加法逻辑比较直观
判断是否其中一个是0,是的话直接返回另一个数 
同符号,做加法,符号不变构造结果 
不同符号,先比较绝对值,不等的话做减法,确保大减小,清除起始的0并判定符号构造结果 
 
BigInteger.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public  BigInteger add (BigInteger val)      if  (val.signum == 0 )         return  this ;     if  (signum == 0 )         return  val;     if  (val.signum == signum)         return  new  BigInteger(add(mag, val.mag), signum);     int  cmp = compareMagnitude(val);     if  (cmp == 0 )         return  ZERO;     int [] resultMag = (cmp > 0  ? subtract(mag, val.mag) : subtract(val.mag, mag));     resultMag = trustedStripLeadingZeroInts(resultMag);     return  new  BigInteger(resultMag, cmp == signum ? 1  : -1 ); } 
减法套路和加法完全一致
BigInteger.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public  BigInteger subtract (BigInteger val)      if  (val.signum == 0 )         return  this ;     if  (signum == 0 )         return  val.negate();     if  (val.signum != signum)         return  new  BigInteger(add(mag, val.mag), signum);     int  cmp = compareMagnitude(val);     if  (cmp == 0 )         return  ZERO;     int [] resultMag = (cmp > 0  ? subtract(mag, val.mag)                        : subtract(val.mag, mag));     resultMag = trustedStripLeadingZeroInts(resultMag);     return  new  BigInteger(resultMag, cmp == signum ? 1  : -1 ); } 
数组采用大端存储的方式,mag[0]存高位,因此运算后可能存在数组前几个数字都是0,采用数组拷贝的方式清除掉
BigInteger.java 1 2 3 4 5 6 7 8 9 private  static  int [] trustedStripLeadingZeroInts(int  val[]) {    int  vlen = val.length;     int  keep;          for  (keep = 0 ; keep < vlen && val[keep] == 0 ; keep++)         ;     return  keep == 0  ? val : java.util.Arrays.copyOfRange(val, keep, vlen); } 
因为没有了起始的0,因此数组内每个数字都是有效的,比较绝对值时更加直观,比较长度即可初步判断大小
BigInteger.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 final  int  compareMagnitude (BigInteger val)      int [] m1 = mag;     int  len1 = m1.length;     int [] m2 = val.mag;     int  len2 = m2.length;     if  (len1 < len2)         return  -1 ;     if  (len1 > len2)         return  1 ;     for  (int  i = 0 ; i < len1; i++) {         int  a = m1[i];         int  b = m2[i];         if  (a != b)             return  ((a & LONG_MASK) < (b & LONG_MASK)) ? -1  : 1 ;     }     return  0 ; }