2010-08-06 72 views
16

現在,我使用這個設置在一個字節/復位各個位:簡單的方法來設置/取消個別位

if (bit4Set) 
    nbyte |= (1 << 4); 
else 
    nbyte &= ~(1 << 4); 

但是,你不能這樣做,在一個更爲簡單/優雅辦法?像在單個操作中設置或取消設置位一樣?

注:我知道我可以寫一個函數來做到這一點,我只是想知道我是不是會重新發明輪子。

+4

http://stackoverflow.com/questions/47981/how-do-you-set-clear-and-toggle-a-single-bit-in-c – obelix 2010-08-06 12:43:08

+4

@obelix:所以這是怎麼一回事那些小問題已經回答了? + 112/+ 241,90收藏?很好的問題/偉大的答案黃金徽章? – 2010-08-06 13:09:06

回答

12

當然!這將是比較明顯的,如果你擴大你的代碼的|=&=,但你可以這樣寫:

nbyte = (nbyte & ~(1<<4)) | (bit4Set<<4); 

注意bit4Set必須爲零或一個 - 不是任何非零值 - 這個工作。

+0

取消設置,然後根據bit4set設置。沒有想到這一點。韓國社交協會。 – djeidot 2010-08-06 14:00:58

+7

'nbyte =(nbyte&〜(1 << 4))| ((!! bit4Set)<< 4)'處理bit4Set不是零或一。 – 2010-08-06 14:38:29

11

把它放在一個函數中,布爾類型將爲所有的bitval輸入強制執行0,1。

int change_bit(int val, int num, bool bitval) 
{ 
    return (val & ~(1<<num)) | (bitval << num); 
} 
+0

如果我把它放到一個函數中,我寧願使用我寫的代碼。不過,這是對的。 – djeidot 2010-08-06 14:02:34

+5

如果讓編譯器用C++內聯這個函數,那麼它就會像使用表達式本身一樣快,而且你會得到可讀性獎金。 – 2010-08-06 14:13:31

0
nbyte |= (1 << 4); 

如果分配,(1 << 4)的右手邊,永遠是這樣一個常數,那麼這將可能是由編譯器進行優化,這將是導致組裝簡單:

mov r0, _nbyte 
mov r1, 10H   ; here is the optimization, no bit shift occured 
or r0, r1 
st _nbyte, r0 
+3

這是對「如何以nbyte設置第4位?」這個問題的回答。問題是「如何根據bit4Set的值以nbyte爲單位設置或取消設置bit 4?」 – 2010-08-06 12:55:45

+0

謝謝。我誤解了這個問題。我應該刪除我的答案嗎? – Donotalo 2010-08-07 05:09:42

6

這是一個完全明智而完全標準的習語。

+1

+1我在微控制器代碼中多次看到這個習慣用法。 – 2010-08-06 13:42:03

+0

它可能會引入會影響性能的分支。Pascal Cuoq的答案可能不易讀,但表現更好。 – 2017-12-18 10:54:23

4

你有沒有考慮給你的位分配助記符和/或標識符,而不是用數字來引用它們?

舉一個例子,假設設置位4啓動一個核反應堆SCRAM。我們將其稱爲INITIATE_SCRAM,而不是將其稱爲「第4位」。下面是這個代碼可能是什麼樣子:

int const INITIATE_SCRAM = 0x10; // 1 << 4 

... 

if (initiateScram) { 
    nbyte |= INITIATE_SCRAM; 
} else { 
    nbyte &= ~INITIATE_SCRAM; 
} 

這不一定是任何更有效(優化後)比你原來的代碼,但它是一個更清晰一點,我想,大概更容易維護。

+0

這幾乎是一回事。我實際上使用標識符,我只是沒有把它們放在例子中。 – djeidot 2010-08-06 14:04:02

2

這被標記爲C++所以你有沒有考慮使用std::bitset而不是自己做所有的位操作?然後你可以使用數組表示法:bits[3] = bit4Set來設置適當的位。

相關問題