【问题标题】:How are BigInteger storedBigInteger 是如何存储的
【发布时间】:2014-05-11 20:16:18
【问题描述】:

我需要生成 512 位的 BigInts,但我不确定下面两个哪个是真的:

512 位是指1010101010...001010 的 512 位,然后转换成它所代表的小数?

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

【问题讨论】:

  • 每一位代表一个0或1。
  • 如果你真的想知道,在你的JDK安装目录下的src.zip文件中查找源代码。

标签: java biginteger bits bigint


【解决方案1】:

从源代码来看,它们存储在int 数组中

这个 BigInteger 的大小,按照 big-endian 顺序:这个数组的第 0 个元素是这个大小中最重要的 int。幅度必须是“最小的”,因为最重要的 int (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 

【讨论】:

  • 但它是存储每个数组条目的数字还是 32 位整数部分?
【解决方案2】:

从概念上讲,BigInteger 将整数转换为任意长度的位串,然后将位串拆分为 4 个字节。然后,将每个 4bytes 的结果分配给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 signum1 (00000000 00000000 00000000 00000001)。
  • final int[] mag 中的mag[0]1234567890 (01001001 10010110 00000010 11010010)。是的,mag 只有一个元素。

让我们表示更大的整数:

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
  • final int signum1 (00000000 00000000 00000000 00000001)。
  • final int[] mag 中的mag[0]-1420514932 (10101011 01010100 10101001 10001100)。
  • final int[] mag 中的mag[1]-350287150 (11101011 00011111 00001010 11010010)。

当我们用负整数实例化BigInteger 实例时:

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
  • final int signum-1 (11111111 11111111 11111111 11111111)。
  • final int[] mag 中的mag[0]1234567890 (01001001 10010110 00000010 11010010)。是的,mag 存储号码的大小
  • 当我们调用toByteArray() 时,BigIntegermag 数组的幅度表示转换为2 的补码表示,因为signum-1,表示负值。所以,不要将toByteArray 视为BigInteger 的内部表示。

当我们用零实例化一个BigInteger 实例时:

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
  • final int signum0 (00000000 00000000 00000000 00000000)。
  • final int[] 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    • 1970-01-01
    • 2011-12-26
    相关资源
    最近更新 更多