我相對新的整個位移和C++。如何獲得第n位值
比方說,我有一個uint8_t 00100100
(36),我想檢查是否設置了第3位。 這裏是代碼如何即時做到這一點,只有一個位。
uint8_t x = 36;
if(x&1<<3)
printf("is set");
我怎麼可以檢查,如果這是第3 或第6位設置?我想檢查幾個比特的組合,如5或7或8。
什麼是最優雅的方式來做到這一點?
我相對新的整個位移和C++。如何獲得第n位值
比方說,我有一個uint8_t 00100100
(36),我想檢查是否設置了第3位。 這裏是代碼如何即時做到這一點,只有一個位。
uint8_t x = 36;
if(x&1<<3)
printf("is set");
我怎麼可以檢查,如果這是第3 或第6位設置?我想檢查幾個比特的組合,如5或7或8。
什麼是最優雅的方式來做到這一點?
通過數字位置檢查位是正確的方法之一,但它使代碼依賴於幻數,這使得它更難以閱讀和維護。
通常,在檢查位掩碼時,有一個檢查某個特定標記的目標,比如說一個硬件寄存器。
想象一下,例如,你的整數的每一位代表你家特定的光,並且要檢查衛生間和廚房是否在:
enum LightMask {
ENTRANCE = 0x01,
LIVING_ROOM = 0x02,
RESTROOM = 0x04,
KITCHEN = 0x08,
BATHROOM = 0x10,
BEDROOM1 = 0x20,
BEDROOM2 = 0x40,
ATTIC = 0x80
};
uint8_t lightsOn = GetLightsOn();
if (lightsOn & (BATHROOM | KITCHEN)) {
// ...
}
這是優雅的,易於理解和可以很容易地修改。
枚舉也可以在不花錢的編譯器換擋,如果你想明確地使用位的位置,而不是常量的比特來表示:
enum LightMask {
ENTRANCE = 1 << 0,
LIVING_ROOM = 1 << 1,
RESTROOM = 1 << 2,
KITCHEN = 1 << 3,
BATHROOM = 1 << 4,
BEDROOM1 = 1 << 5,
BEDROOM2 = 1 << 6,
ATTIC = 1 << 7
};
雖然用於分配枚舉值的常量bitshift表達式可以增強可讀性,但沒有任何缺點(因爲OP明確要求關於移位)。 – 2014-12-10 22:49:21
@πάνταῥεῖ沒錯,好點。 – SirDarius 2014-12-10 22:49:59
uint8_t x = 36;
if (x & ((1 << 2) | (1 << 5)))
printf("is set");
,或者如果你知道十六進制:
uint8_t x = 36;
if (x & 0x24)
printf("is set");
0x24 = 36.這是從第3位還是第6位得出的? – user1930254 2014-12-10 22:45:16
@ user1930254是,'(1 << 2)| (1 << 5)'相當於'(4)+(32)',它是'36'。 – Julian 2014-12-10 22:47:54
如果您不知道哪個位要檢查,直到運行時的位置,一個方法是讓一個函數,所以你可以調用它的任何第n位要檢查:
bool IsBitSet(uint8_t num, int bit)
{
return 1 == ((num >> bit) & 1);
}
uint8_t x = 37; //00100101
for (int i = 0; i < 8; ++i)
{
if (IsBitSet(x, i))
printf("%dth bit is set\n", i);
else
printf("%dth bit not set\n", i);
}
輸出將是:
0th bit is set
1th bit is not set
2th bit is set
3th bit is not set
4th bit is not set
5th bit is set
6th bit is not set
7th bit is not set
如果我想檢查第3位或6位是否被設置:
uint8_t x = 36; //00100100
if (IsBitSet(x, 2) || IsBitSet(x, 5))
printf("bit 3 and/or bit 6 is set\n");
你也可以將這個功能inline
到可能提高工作效率。
可能DUP http://stackoverflow.com/questions/523724/cc-check-if-one-bit-is-set-in-ie-int-variable – 2014-12-10 22:27:11
假設最右邊的位是第一位而不是第零位,只有「<< 2」將第三位移到1的地方。 – 2014-12-10 22:27:35
這些位有沒有具體含義?一個乾淨的方法可能是定義與每個位的語義相關的命名常量。 – SirDarius 2014-12-10 22:30:25