gpt4 book ai didi

java - BigInteger、BitSet 及其位和字节顺序

转载 作者:行者123 更新时间:2023-12-01 20:52:03 25 4
gpt4 key购买 nike

考虑以下代码(java8):

@Test
public void testBigIntegerVsBitSet() throws Throwable
{
String bitString529 = "00000010 00010001"; // <- value = 529 (LittleEndian)
byte[] arr529 = new byte[] { 0x02, 0x11 }; // <- the same as byte array (LittleEndian)
BigInteger bigIntByString = new BigInteger( bitString529.replace( " ", ""), 2); // throws if there is a blank!
BigInteger bigIntByArr = new BigInteger( arr529);
BitSet bitsetByArr = BitSet.valueOf( arr529); // interpretes bit-order as LittleEndian, but byte-order as BigEndian !!!

System.out.println( "bitString529 : " + bitString529); // bitString529 : 00000010 00010001
System.out.println( "arr529.toString : " + Arrays.toString( arr529)); // arr529.toString : [2, 17]
System.out.println( "bigIntByString : " + bigIntByString); // bigIntByString : 529
System.out.println( "bigIntByArr : " + bigIntByArr); // bigIntByArr : 529
System.out.println( "bitsetByArr : " + bitsetByArr.toString() ); // bitsetByArr : {1, 8, 12}
System.out.println( "expecting : {0, 4, 9}"); // expecting : {0, 4, 9}

String bigIntByStringStr = toBitString( bigIntByString::testBit);
String bigIntByArrStr = toBitString( bigIntByArr::testBit);
String bitsetByArrStr = toBitString( bitsetByArr::get);

System.out.println( "bigIntByStringStr: " + bigIntByStringStr); // bigIntByStringStr: 1000100001000000
System.out.println( "bigIntByArrStr : " + bigIntByArrStr); // bigIntByArrStr : 1000100001000000
System.out.println( "bitsetByArrStr : " + bitsetByArrStr ); // bitsetByArrStr : 0100000010001000
}

private String toBitString( Function<Integer, Boolean> aBitTester)
{
StringBuilder sb = new StringBuilder();
for ( int i = 0; i < 16; i++ )
{
sb.append( aBitTester.apply( i) ? "1" : "0");
}
return sb.toString();
}

这证明 BitSet 将字节数组解析为 BIG_ENDIAN,而将(单个字节的)位顺序解释为 LITTLE_ENDIAN。相反,BigInteger 以 LITTLE_ENDIAN 解释两者,即使是通过位字符串加载时也是如此。

特别是两个类的位索引(BitInteger::testBit 与 BitSet::get)的迭代会产生不同的结果。

造成这种不一致的原因是什么?

最佳答案

Endianess 主要指字节的顺序,而不是各个位的顺序。后者与大多数应用程序无关,因为您无法对内存中的各个位进行寻址。因此,字节中位的字节顺序仅在重要的情况下使用,例如串行数据总线,否则字节通常被视为它们表示的没有任何字节顺序的数字( cf. WikipediaCan endianness refer to bits order in a byte? 的答案)。

因此,BitSet 将字节视为首先具有最低有效位,这样当您给它字节 0x01 时,您会得到具有最低有效位的预期结果位设置,无论它使用什么字节顺序来排序。这就是为什么使用 BigIntegerBitSet 的输出仅在字节顺序上有所不同。

请注意,对于字节顺序,BitSet 使用小字节序,而 BigInteger 使用大字节序(与您声称的不同)。

至于为什么BitSet使用与BigInteger不同的字节序,我们只能推测。请注意,受人尊敬的 BitSet 方法要新得多(仅在 Java 1.7 中引入),因此自从引入 BigInteger 以来,小端与大端顺序的重要性可能已经发生了变化.

关于java - BigInteger、BitSet 及其位和字节顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43171915/

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