考虑下面的代码(java8):BigInteger,以位集合和它们的位和字节顺序
@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();
}
其中prooves该位集合解析字节数组作为BIG_ENDIAN而它interpretes比特顺序(一个字节)为LITTLE_ENDIAN 。相反,BigInteger在LITTLE_ENDIAN中解释了这两种情况,即使通过位串加载也是如此。
特别是两个类的位索引(BitInteger :: testBit与BitSet :: get)的迭代提供了不同的结果。
是否有这种不一致的原因?
对不起,我总是对BIG_ENDIAN这个词感到困惑。我上面的说法是基于最后一个最重要的字节的想象。显然,常识是相反的,你是对的。 – Heri
但是我的问题是:为什么BitSet以相反的方式运行是否有充分的理由? – Heri
是的,在某些情况下,位排序很重要。例如编码base64串中的RSA模数(将比特流分成6比特字)或QR码编码(将比特流分成11比特字)。 – Heri