現在,我使用這個設置在一個字節/復位各個位:簡單的方法來設置/取消個別位
if (bit4Set)
nbyte |= (1 << 4);
else
nbyte &= ~(1 << 4);
但是,你不能這樣做,在一個更爲簡單/優雅辦法?像在單個操作中設置或取消設置位一樣?
注:我知道我可以寫一個函數來做到這一點,我只是想知道我是不是會重新發明輪子。
現在,我使用這個設置在一個字節/復位各個位:簡單的方法來設置/取消個別位
if (bit4Set)
nbyte |= (1 << 4);
else
nbyte &= ~(1 << 4);
但是,你不能這樣做,在一個更爲簡單/優雅辦法?像在單個操作中設置或取消設置位一樣?
注:我知道我可以寫一個函數來做到這一點,我只是想知道我是不是會重新發明輪子。
當然!這將是比較明顯的,如果你擴大你的代碼的|=
和&=
,但你可以這樣寫:
nbyte = (nbyte & ~(1<<4)) | (bit4Set<<4);
注意bit4Set
必須爲零或一個 - 不是任何非零值 - 這個工作。
取消設置,然後根據bit4set設置。沒有想到這一點。韓國社交協會。 – djeidot 2010-08-06 14:00:58
'nbyte =(nbyte&〜(1 << 4))| ((!! bit4Set)<< 4)'處理bit4Set不是零或一。 – 2010-08-06 14:38:29
把它放在一個函數中,布爾類型將爲所有的bitval輸入強制執行0,1。
int change_bit(int val, int num, bool bitval)
{
return (val & ~(1<<num)) | (bitval << num);
}
如果我把它放到一個函數中,我寧願使用我寫的代碼。不過,這是對的。 – djeidot 2010-08-06 14:02:34
如果讓編譯器用C++內聯這個函數,那麼它就會像使用表達式本身一樣快,而且你會得到可讀性獎金。 – 2010-08-06 14:13:31
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
這是對「如何以nbyte設置第4位?」這個問題的回答。問題是「如何根據bit4Set的值以nbyte爲單位設置或取消設置bit 4?」 – 2010-08-06 12:55:45
謝謝。我誤解了這個問題。我應該刪除我的答案嗎? – Donotalo 2010-08-07 05:09:42
這是一個完全明智而完全標準的習語。
+1我在微控制器代碼中多次看到這個習慣用法。 – 2010-08-06 13:42:03
它可能會引入會影響性能的分支。Pascal Cuoq的答案可能不易讀,但表現更好。 – 2017-12-18 10:54:23
你有沒有考慮給你的位分配助記符和/或標識符,而不是用數字來引用它們?
舉一個例子,假設設置位4啓動一個核反應堆SCRAM。我們將其稱爲INITIATE_SCRAM
,而不是將其稱爲「第4位」。下面是這個代碼可能是什麼樣子:
int const INITIATE_SCRAM = 0x10; // 1 << 4
...
if (initiateScram) {
nbyte |= INITIATE_SCRAM;
} else {
nbyte &= ~INITIATE_SCRAM;
}
這不一定是任何更有效(優化後)比你原來的代碼,但它是一個更清晰一點,我想,大概更容易維護。
這幾乎是一回事。我實際上使用標識符,我只是沒有把它們放在例子中。 – djeidot 2010-08-06 14:04:02
這被標記爲C++所以你有沒有考慮使用std::bitset
而不是自己做所有的位操作?然後你可以使用數組表示法:bits[3] = bit4Set
來設置適當的位。
http://stackoverflow.com/questions/47981/how-do-you-set-clear-and-toggle-a-single-bit-in-c – obelix 2010-08-06 12:43:08
@obelix:所以這是怎麼一回事那些小問題已經回答了? + 112/+ 241,90收藏?很好的問題/偉大的答案黃金徽章? – 2010-08-06 13:09:06