簡體   English   中英

為什么 Java BitSet 打包成 6 個字節?

[英]Why is a Java BitSet packed in 6 bytes?

我正在研究BitSet ,但我不清楚以下幾點:

  1. 當我們傳遞位數時,會除以6 為什么使用6而不是 2 的冪?
  2. 初始化底層數組時,為什么在除以6之前先減 1,然后加 1?

我假設您正在詢問 JDK 中的這段代碼:

private static int wordIndex(int bitIndex) {
    return bitIndex >> ADDRESS_BITS_PER_WORD; // ADDRESS_BITS_PER_WORD is 6, question 1
}

public BitSet(int nbits) {
    // nbits can't be negative; size 0 is OK
    if (nbits < 0)
        throw new NegativeArraySizeException("nbits < 0: " + nbits);

    initWords(nbits);
    sizeIsSticky = true;
}

private void initWords(int nbits) {
    words = new long[wordIndex(nbits-1) + 1]; // question 2
}

initWords初始化一個long[]來支持這些位,基本上將這些位存儲到 64 位的“字”中。 請注意,這似乎是一個實現細節。 這個long[]應該有多長? 好吧,它應該是最后一個單詞的單詞索引+ 1,因為索引是從零開始的。

最后一個詞的索引是多少? 嗯, wordIndex方法可以告訴我們一個的單詞索引,所以如果我們給它最后一位的索引, nbits - 1 (同樣因為索引是從零開始的),它會給我們想要的。 這應該回答你的第二個問題。

wordIndex如何找到單詞索引? 嗯,一個long有 64 位,所以我們只需要將bitIndex除以 64。除以 64 的另一種方法是什么? 左移 6 次,因為 64 = 2 的 6 次方。有關更多信息,請參閱此帖子

我想你談談這個 class 的實現?

它在源文件的注釋中這樣說:

    /*
     * BitSets are packed into arrays of "words."  Currently a word is
     * a long, which consists of 64 bits, requiring 6 address bits.
     * The choice of word size is determined purely by performance concerns.
     */

因此,對於給定的位數,低 6 位用於尋址 64 位字的位,其余位用於尋址字。


對於第 2 點,我想你在談論

wordIndex(nbits-1) + 1

這是

bitIndex >> ADDRESS_BITS_PER_WORD
  • 假設你想初始化一個最初有 0 個條目的 BitSet。 然后你需要一個大小為 0 的數組。
  • 假設您要初始化一個最初包含 1 到 64 個條目的 BitSet。 然后你需要一個大小為 1 的數組。
  • 假設您要初始化一個最初包含 65 到 128 個條目的 BitSet。 然后你需要一個大小為 2 的數組。

等等。

這意味着,您將 map 原始范圍 (1-64, 65-128) 改為“減一” (0-63, 64-127),除以 64 (0, 1) 並再次增加結果 (1, 2)獲取數組中所需單詞的數量。


為了證明兩者:

假設您想要一個包含 128 個條目的 BitSet。 你初始化它,你會得到一個包含 2 個 64 位條目的數組。 為什么?

這是因為 wach 字可以容納 64 位,所以為了容納 128 位,您需要 2 個數組條目:

(128-1)/64 + 1 = 127/64 + 1 = 1 + 1 = 2。(請記住,integer 將 go 划分為較低的值。)

現在,您要設置 bis 5、13 和 66。

第 5 位和第 13 位很好 - 您只需在索引 0 處設置字中的第 5 位和第 13 位。

但是你用 66 做什么呢? 每個字只有 64 位。 (0..63)

好吧,在這種情況下,您在數組中執行的每個步驟都減去 64。 所以你 go 到索引 1 處的單詞和“補償”,你 go 從 66 到 2。

這正是這些位操作所發生的事情:從這些位索引中的每一個,低 6 位被取出並用作相應字中的位地址。

5 = 0 000101 = 0/5 13 = 0 001101 = 0/13 66 = 1 000001 = 1/2

所以

  • 5 通過設置字 0 中的位 5 來設置。
  • 13 通過設置字 0 中的位 13 來設置。
  • 通過設置字 1 中的位 2 來設置 66。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM