码迷,mamicode.com
首页 > 移动开发 > 详细

HappyBKs强迫症——BigInteger有多大?

时间:2015-10-01 21:52:08      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:

现在什么事都动不动大数据了。连个int也level up成了BigInteger。在一些场景似乎还不得不使用它。

于是有人贱贱地问:“这个天到底有多大呢?”

技术分享

不,应该是“这个BigInteger到底有多大呢?”

让我们来看看BigInteger的内部结构吧。

BigInteger中,一个大int其实是由一个int数组实现的,即mag。还有一个int数值signum,用来作为正负标记。

public class BigInteger extends Number implements Comparable<BigInteger> {
    /**
     * The signum of this BigInteger: -1 for negative, 0 for zero, or
     * 1 for positive.  Note that the BigInteger zero <i>must</i> have
     * a signum of 0.  This is necessary to ensures that there is exactly one
     * representation for each BigInteger value.
     *
     * @serial
     */
    final int signum;

    /**
     * The magnitude of this BigInteger, in <i>big-endian</i> order: the
     * zeroth element of this array is the most-significant int of the
     * magnitude.  The magnitude must be "minimal" in that the most-significant
     * int ({@code mag[0]}) must be non-zero.  This is necessary to
     * ensure that there is exactly one representation for each BigInteger
     * value.  Note that this implies that the BigInteger zero has a
     * zero-length mag array.
     */
    final int[] mag;

那么,如何将一个范围大于int范围的数存在BigInteger的mag数组中呢?

BigInteger有很多重载的构造器,我们挑选其中一个来说明就明白了:

    /**
     * Constructs a BigInteger with the specified value, which may not be zero.
     */
    private BigInteger(long val) {
        if (val < 0) {
            val = -val;
            signum = -1;
        } else {
            signum = 1;
        }

        int highWord = (int)(val >>> 32);
        if (highWord==0) {
            mag = new int[1];
            mag[0] = (int)val;
        } else {
            mag = new int[2];
            mag[0] = highWord;
            mag[1] = (int)val;
        }
    }

我们可以看到,对于long长度为8字节,正好是两个int的大小。在上面的构造器中,先通过向右移位32位,取得long的高32位的数,如果为0,则表示long的实际值并没有超过int的范围,于是mag数组只申请一个int的大小,保存long的低32位即可;如果不为0,则说明long的实际值已经超出int的范围,这时候,mag申请两个int大小,将高位32位存在mag[0],低位32位存在mag[1]。


也就是位数高的存在前面,位数低的存在后面。


好吧,回到原先的问题,BigInteger有多大?

mag既然是数组,那么它的长度收到下标范围的影响,即mag的个数不会超过int的最大值,即2的31次方-1,即2147483647。那么每个int是32位。那么mag所能够大表的位数是2147483647*32。

所以,BigInteger的范围应该是[-22147483647*32-1 ,22147483647*32-1 -1]




HappyBKs强迫症——BigInteger有多大?

标签:

原文地址:http://my.oschina.net/happyBKs/blog/513133

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!