2013-03-06 91 views
10

我在從一個字節中抓取n位時遇到了一些麻煩。從字節中抓取n位

我有一個無符號的整數。假設我們的十六進制數是0x2A,十進制數是42。在二進制中,它看起來像這樣:0010 1010.我將如何獲取前00位和後010位的3位,並將它們置於不同的整數中?

如果任何人都可以幫助我,這將是偉大的!我知道如何從哪個是簡單地做

int x = (number >> (8*n)) & 0xff // n being the # byte 
我對堆棧溢出另一篇文章中看到

一個字節中提取,但我不知道如何讓單獨的位出字節。如果有人能幫助我,那會很棒!謝謝!

+0

42的前5位(MSB)爲00000,因爲int總是大於1個字節。另外,不存在具有十六進制小數形式的無符號整數。 'int a = 0x2A;'與寫入int a = 42;' – user93353 2013-03-06 19:06:05

回答

14

整數在機器內部表示爲一系列位;幸運的是,對於我們人類來說,編程語言提供了一種機制來向我們顯示這些十進制(或十六進制)的數字,但是這並不會改變它們的內部表示。

您應該修改位運算符&|^~以及移位運算符<<>>,這將有助於您瞭解如何解決這類問題。

的整數的最後3位是:

x & 0x7 

從八最末位開始的5位是:

x >> 3 // all but the last three bits 
    & 0x1F // the last five bits. 
+0

相同這是如何比較性能與只存儲兩個子插入爲兩個32位整數?提取需要一些時間,但它是32個操作較慢? – Kammeot 2014-10-16 16:58:22

+0

@InspiredOne:像這樣的問題不可能在摘要中精確地回答,但很明顯它提高了內存使用量(相對於兩個32位整數,或者相對於兩個字節,因子爲兩倍)提高緩存性能,內存吞吐量和帶寬(如果相關)(傳輸時間或輔助存儲)。由於與其中任何一個因素相比,CPU成本都是微不足道的,所以如果需要多個實例,壓縮數據通常會更快;這對於一對變量來說是不值得的(但它也不會造成太大的影響)。 – rici 2014-10-16 20:36:29

1

只是擺脫你的代碼中的8 *。

int input = 42; 
int high3 = input >> 5; 
int low5 = input & (32 - 1); // 32 = 2^5 
bool isBit3On = input & 4; // 4 = 2^(3-1) 
1

int x = (number >> 3) & 0x1f;

會給你一個整數,其中最後5位是number的8-4位,其他位爲零。

同樣,

int y = number & 0x7;

會給你最後3位的整數設置number最後3位,在剩下的零點。

7

假設你想要hi位從頂部開始,lo位從底部開始。 (在你的榜樣5,3)

top = (n >> lo) & ((1 << hi) - 1) 
bottom = n & ((1 << lo) - 1) 

說明:

對於頂部,先幹掉的下位(右移),則掩蓋了剩餘的與「全一」的面具(如果您有像0010000這樣的二進制數,則減去一個結果0001111 - 與原始數中的0-s相同數1 s)。

對於底部它是一樣的,只是不必關心最初的轉變。

top = (42 >> 3) & ((1 << 5) - 1) = 5 & (32 - 1) = 5 = 00101b 
bottom = 42 & ((1 << 3) - 1) = 42 & (8 - 1) = 2 = 010b 
12

「搶奪」 C中的整數類型的部分是這樣的:

  1. 你你想要的位移位到最低位置。
  2. 您使用&掩蓋你想要的位 - 的人表示「複製此位」零的意思是「忽略」

所以,在你的例子。比方說,我們有許多int x = 42;

前5位:

(x >> 3) & ((1 << 5)-1); 

(x >> 3) & 31; 

,以獲取低三位:

(x >> 0) & ((1 << 3)-1) 

或:

x & 7; 
2

你可以爲此使用位字段。位域是特殊的結構,您可以在其中指定位的變量。

typedef struct { 
    unsigned char a:5; 
    unsigned char b:3; 
} my_bit_t; 

unsigned char c = 0x42; 
my_bit_t * n = &c; 
int first = n->a; 
int sec = n->b; 

位域進行了更詳細的http://www.cs.cf.ac.uk/Dave/C/node13.html#SECTION001320000000000000000

位字段的魅力所描述的,你不必應付移位運算等的符號是很容易的。像操縱位一樣,存在可移植性問題。