Java BigInteger add方法

写了个菲波那切数列的递归,刚开始使用int来返回结果,随便输入个n(得到斐波那契第n个数),结果发现数据变成负数了,明显是溢出了。

int数据类型有四个字节,最大可以实现的数是2的31次方-1。

然后打算使用long类型,结果当我输入n=666时,还是溢出了。long(8字节)类型数据的最大值是2的63次方-1。

具体类型的最大最小值可看下方:

 

所以现在问题就来了,如果想实现一个超大数的整数,应该使用什么呢?

对了,就是 BigInteger。

众所周知,斐波那契数列是前两个数值加起来,所以我就来看了下Biginteger是如何实现add的。

代码如下:

/**
     * Returns a BigInteger whose value is {@code (this + val)}.
     *
     * @param  val value to be added to this BigInteger.
     * @return {@code this + val}
     */
    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);
    }


/**
* Adds the contents of the int arrays x and y. This method allocates
* a new int array to hold the answer and returns a reference to that
* array.
*/
private static int[] add(int[] x, int[] y) {
// If x is shorter, swap the two arrays
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 {
// Add common parts of both numbers
while (yIndex > 0) {
sum = (x[--xIndex] & LONG_MASK) +
(y[--yIndex] & LONG_MASK) + (sum >>> 32);
result[xIndex] = (int)sum;
}
}
// Copy remainder of longer number while carry propagation is required
boolean carry = (sum >>> 32 != 0);
while (xIndex > 0 && carry)
carry = ((result[--xIndex] = x[xIndex] + 1) == 0);

// Copy remainder of longer number
while (xIndex > 0)
result[--xIndex] = x[xIndex];

// Grow result if necessary
if (carry) {
int bigger[] = new int[result.length + 1];
System.arraycopy(result, 0, bigger, 1, result.length);
bigger[0] = 0x01;
return bigger;
}
return result;
}
 

最终结果

 

 最后贴上斐波那契数列递归实现方法:

private static BigInteger getFibonacciN(int n) {
        if(n == 1 || n == 2) {
            return BigInteger.ONE;
        }
        return cycle(BigInteger.ONE, BigInteger.ONE, n -3);
    }

    private static BigInteger cycle(BigInteger s, BigInteger e, int n) {
        if(n == 0) {
            return s.add(e);
        }
        return cycle(e, s.add(e), --n);
    }

如上。

posted @ 2021-01-09 17:36  fanghuiX  阅读(425)  评论(0编辑  收藏  举报