2011-05-14 79 views
5

如何設置十六進制數字中的數字? 我現在有這樣的代碼:設置十六進制數字

int row = 0x00000000; 
row |= 0x3 << 8; 
row |= 0x2 << 4; 
row |= 0x1 << 0; 

printf("Row: 0x%08x", row); 

只要這工作完全正常的「行」只是零。當我將其更改爲這樣的事情:

int row = 0x33333333; 
row |= 0x3 << 8; 
row |= 0x2 << 4; 
row |= 0x1 << 0; 

printf("Row: 0x%08x", row); 

我只是得到這樣的輸出:

行:0x33333333

+0

它「作品」無論如何,但如果你嘗試設置已經被設定位,會發生什麼? – 2011-05-14 13:05:53

回答

10

您應該刪除(使它0)數字第一。

row &= ~(0xf << 4); 

~運算符反轉數字中所有位的值。所以。 0x000000f0變成0xffffff0f

您的代碼應該是這樣的:

row &= ~(0xf << 8); 
row |= 0x3 << 8; 
row &= ~(0xf << 4); 
row |= 0x2 << 4; 
row &= ~(0xf << 0); 
row |= 0x1 << 0; 
3

由於亞歷解釋,你需要清楚你要設置你去之前設置位域。

我想補充,爲什麼你的代碼沒有做你想要的,考慮什麼是二進制級別發生的變化有什麼進一步的評論:

row |= 0x2 << 4; 

| =運算符是「按位要麼」。因此,如果您嘗試設置的位或您傳入的位設置爲1,則結果爲1.在您的代碼中,設置爲0x33333333,因此每個4位十六進制數字是二進制。當你按位或與0X2,你會得到0x3:

/* 0x3 | 0x2 = 0x3 */ 
0011 | 0010 = 0011 

如果您先清除位域,你得到0X2,這是你想要的東西:

/* 0x3 | 0x0 = 0x0 */ 
0011 | 0000 = 0000 

/* 0x0 | 0x2 = 0x2 */ 
0000 | 0010 = 0010 

注意,數據操作使用移位和按位操作不可能在不同平臺之間移植。你可能會碰到試圖運行代碼,依託位移位在不同的字節序的機器問題,或者事實上,如果你嘗試運行在32位計算機上工作的64位機器上的代碼:

http://www.viva64.com/en/a/0004/#ID0EQFDI

維基百科有更多關於位運算:

http://en.wikipedia.org/wiki/Bitwise_operation