代码之家  ›  专栏  ›  技术社区  ›  George Irimiciuc

BigInteger是如何存储的

  •  2
  • George Irimiciuc  · 技术社区  · 12 年前

    我需要生成512位BigInt,但我不确定以下两个值中的哪一个是真的:

    512位表示512位 1010101010...001010 然后将其转换为它表示的小数?

    或者是512位 0-9 ,所以基本上是一个数字范围为0-9的512位数字?类似于12414124124……54543=512位数字。

    2 回复  |  直到 12 年前
        1
  •  4
  •   Keerthivasan    12 年前

    从源代码中,它们存储在 int 大堆

    这个BigInteger的大小,按大端顺序排列:这个数组的第零个元素是大小的最重要的整数。幅度必须为“最小”,因为最高有效整数(mag[0])必须为非零。这对于确保每个BigInteger值只有一个表示形式是必要的。注意,这意味着BigInteger零具有零长度mag数组。

    118 
    119     int[] mag;
    120 
    121     // These "redundant fields" are initialized with recognizable nonsense
    122     // values, and cached the first time they are needed (or never, if they
    123     // aren't needed).
    124 
    
        2
  •  1
  •   rosshjb    4 年前

    概念上, BigInteger 将整数转换为任意长度的位串,然后将位串拆分4个字节。然后,将每个4字节的结果分配给 mag 阵列:

    BigInteger bi = new BigInteger("1234567890");
    
    byte[] bytes = bi.toByteArray();
    
    String rs = "";
    for (byte b : bytes) {
        String bs1 = Integer.toBinaryString(b & 0xff);
        String bs2 = String.format("%8s", bs1).replace(' ', '0');
        rs = rs + bs2 + " ";
    }
    System.out.println(bi.signum());     // 1
    System.out.println(bi.bitLength());  // 31
    System.out.println(rs);              // 01001001 10010110 00000010 11010010
    
    • 这个 final int signum 1 ( 00000000 00000000 00000000 00000001 ).
    • 这个 mag[0] 在里面 final int[] mag 1234567890 ( 01001001 10010110 00000010 11010010 ). 对 美格 只有一个元素。

    让我们表示更大的整数:

    BigInteger bi = new BigInteger("12345678901234567890");
    
    byte[] bytes = bi.toByteArray();
    
    String rs = "";
    for (byte b : bytes) {
        String bs1 = Integer.toBinaryString(b & 0xff);
        String bs2 = String.format("%8s", bs1).replace(' ', '0');
        rs = rs + bs2 + " ";
    }
    System.out.println(bi.signum());     // 1
    System.out.println(bi.bitLength());  // 64
    System.out.println(rs);              // 00000000 10101011 01010100 10101001 10001100 11101011 00011111 00001010 11010010
    
    • 这个 最终整数符号 1. ( 00000000 00000000 00000000 00000001 ).
    • 这个 磁[0] 在里面 最终整数[]mag -1420514932 ( 10101011 01010100 10101001 10001100 ).
    • 这个 mag[1] 在里面 最终整数[]mag -350287150 ( 11101011 00011111 00001010 11010010 ).

    当我们实例化 大整数 具有负整数的实例:

    BigInteger bi = new BigInteger("-1234567890");
    
    byte[] bytes = bi.toByteArray();
    
    String rs = "";
    for (byte b : bytes) {
        String bs1 = Integer.toBinaryString(b & 0xff);
        String bs2 = String.format("%8s", bs1).replace(' ', '0');
        rs = rs + bs2 + " ";
    }
    System.out.println(bi.signum());     // -1
    System.out.println(bi.bitLength());  // 31
    System.out.println(rs);              // 10110110 01101001 11111101 00101110
    
    • 这个 最终整数符号 -1 ( 11111111 11111111 11111111 11111111 ).
    • 这个 磁[0] 在里面 最终整数[]mag 1234567890 ( 01001001 10010110 00000010 11010010 ). 对 美格 存储编号的 巨大 .
    • 当我们打电话时 toByteArray() , 大整数 转换 美格 数组的大小表示转换为2的补码表示,因为 signum -1 ,表示负值。所以,不要治疗 toByteArray 大整数 的内部表示。

    当我们实例化 大整数 实例为零:

    BigInteger bi = new BigInteger("0");
    
    byte[] bytes = bi.toByteArray();
    
    String rs = "";
    for (byte b : bytes) {
        String bs1 = Integer.toBinaryString(b & 0xff);
        String bs2 = String.format("%8s", bs1).replace(' ', '0');
        rs = rs + bs2 + " ";
    }
    System.out.println(bi.signum());     // 0
    System.out.println(bi.bitLength());  // 0
    System.out.println(rs);              // 00000000
    
    • 这个 最终整数符号 0 ( 00000000 00000000 00000000 00000000 ).
    • 这个 最终整数[]mag 没有元素;零大小数组。 The magnitude must be "minimal" in that the most-significant int (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
    推荐文章