2011-03-01 22 views
1

在這個問題中,爲簡單起見,假設所有整數都是無符號的。C中的「動態位域」

假設我想編寫2個函數,pack和unpack,它們可以將更小寬度的整數轉換成64位整數。但是,整數的位置和寬度是在運行時給出的,所以我不能使用C位域。

最快就是用一個例子來解釋。爲了簡單起見,我將與8位整數說明:

   * * 
bit # 8 7 6 5 4 3 2 1 
myint 0 1 1 0 0 0 1 1 

假設我想「解壓」在位置5,寬度爲2。這些的整數。用星號標記的兩個比特。該操作的結果應該是0b01。同樣,如果我在寬度爲6的位置2解包,我會得到0b100011。

我可以很容易地寫一個位移左移右移的解壓縮函數。

但我想不出一個明確的方式來寫一個等效的「包」功能,這將做相反的事情。

說給出的整數0b11,在位置5包裝成敏(從上面)和寬度2將產生

   * * 
bit # 8 7 6 5 4 3 2 1 
myint 0 1 1 1 0 0 1 1 

最佳我想出了涉及大量concatinating比特串與OR,<的<和>>。在我執行和測試之前,也許有人看到一個聰明的快速解決方案?

回答

5

關閉我的頭頂,未經測試。

int pack(int oldPackedInteger, int bitOffset, int bitCount, int value) { 
    int mask = (1 << bitCount) -1; 
    mask <<= bitOffset; 
    oldPackedInteger &= ~mask; 
    oldPackedInteger |= value << bitOffset; 
    return oldPackedInteger; 
} 

在您的例子:

int value = 0x63; 
value = pack(value, 4, 2, 0x3); 

要在4(可帶兩個比特)的偏移寫入值 「3」 時0x63是電流值。

+1

是的。對於解包方法也是類似的:OP不需要使用「左移右移」來解壓縮;右移後跟一個'&'就可以實現。 – LukeH 2011-03-01 01:46:59

+0

@Luke:雖然我不太明白這個例子。解壓縮結果如何導致0x0b01和0xb100011? – EboMike 2011-03-01 01:49:46

+0

@EboMike,位5是0,位6是1. – Max 2011-03-01 01:51:21