[英]BigInteger, BitSet and their bit and byte order
考慮以下代碼(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)的迭代提供了不同的結果。
是否存在這種不一致的原因?
字節序大多僅指字節的順序,而不是指各個位的順序。 后者與大多數應用程序無關,因為例如您不能尋址內存中的各個位。 因此,字節中的位的字節序僅在重要的情況下使用,例如串行數據總線,否則,字節通常被視為它們所代表的數字而沒有任何字節序(請參閱Wikipedia ,關於“ 可以字節序”的答案是指位)以字節為單位? )。
因此,由於此BitSet
將字節視為其最低有效位,因此當您將字節賦予0x01
,無論字節排序使用何種字節序,都將獲得最低位的預期結果。 這就是為什么使用BigInteger
和BitSet
輸出僅在字節順序上有所不同的原因。
請注意,對於字節順序, BitSet
使用小字節序,而BigInteger
使用大字節序(與您聲明的內容不同)。
至於BitSet
為什么使用與BigInteger
不同的字節序,我們只能推測。 請注意,受人尊敬的BitSet
方法更新得多(僅在Java 1.7中引入),因此自BigInteger
引入以來,小字節序和大字節序的重要性可能已經改變。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.