gpt4 book ai didi

Java 从 BigInteger 到 BitSet 再返回

转载 作者:行者123 更新时间:2023-11-30 08:54:09 27 4
gpt4 key购买 nike

Java 8 中,下面的代码将整数 3 转换为位集并打印 {0, 1} 表示 的位表示3 在位置 0111

System.out.println(BitSet.valueOf(new long[]{3}));

我有兴趣将具有较大值的 BigIntegerlong 转换为相应的 BitSet,比如 10000000 > 然后返回 - 让 BitSet 对象(位表示)将其转换为 BigInteger(long)。我还想知道对于各种整数值,哪种表示占用更多内存?

最佳答案

您可以使用 BigInteger.toByteArray()BitSet.toByteArray()对于这些:

BigInteger bi = new BigInteger("31415926535");
bi = bi.multiply(new BigInteger("271828"));
System.out.println(bi);
BitSet bs = BitSet.valueOf(bi.toByteArray());
System.out.println(bs);
BigInteger bi2 = new BigInteger(bs.toByteArray());
System.out.println(bi2);

您可以使用 BigInteger(byte[]) 的构造函数将字节数组转换为 BigIntegerBitSet.valueOf(byte[])将数据转换为所需的值。

对于给定的代码,它输出:

8539728478155980
{1, 2, 3, 4, 9, 10, 12, 14, 17, 18, 20, 22, 23, 25, 27, 28, 29, 30, 32, 33, 35, 37, 38, 42, 44, 45, 50, 51, 54, 55}
8539728478155980

请注意,使用了2-complement 表示法。因此对于负数,它会产生额外的。而 2^64-1 将需要超过 64 位来表示。这也适用于 big endian。 (请参阅下面修改后的答案)。

编辑:但是这种方法有一个问题:如果有尾零,程序不会考虑这些。这可能很重要,因为它们是表示的一部分。您可以通过添加拖尾位来解决此问题:

public static BitSet convertTo (BigInteger bi) {
byte[] bia = bi.toByteArray();
int l = bia.length;
byte[] bsa = new byte[l+1];
System.arraycopy(bia,0,bsa,0,l);
bsa[l] = 0x01;
return BitSet.valueOf(bsa);
}

public static BigInteger convertFrom (BitSet bs) {
byte[] bsa = bs.toByteArray();
int l = bsa.length-0x01;
byte[] bia = new byte[l];
System.arraycopy(bsa,0,bia,0,l);
return new BigInteger(bia);
}

并调用它:

BigInteger bi = new BigInteger("20000000");
System.out.println(bi);

BitSet bs = convertTo(bi);
System.out.println(bs);

BigInteger bi2 = convertFrom(bs);
System.out.println(bi2);

关于内存使用情况

一般来说,这两种方法将使用大致相同的位数。对于第一个实现(没有大小标记,因此会出现错误),有时 BitSet 方法使用的字节可能比 BigInteger 方法少一个字节。对于大小标记(第二种方法),情况恰恰相反:一般情况下,BitSet 将始终使用一个额外的字节,除了极少数情况。

关于Java 从 BigInteger 到 BitSet 再返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29526985/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com