<< 左移 右端補零,操作的物件是 任意 int char 這裡任意是指有無符號的意思。
>> 右移 無符號數或者是正數不用考慮是左端補0, 負數看實現【一些實現補0,一些保留符號位,這種比較科學吧】
~ 按位取反 【一元運算子】
& 按位與
^ 按位異或
| 按位或
為了保證可移植性,暫存器當然用unsinged char 或者unsinged int ,當然更詳細一點的posix標準裡的
1位元組 uint8_t
2位元組 uint16_t
4位元組 uint32_t
8位元組 uint64_t
當然有符號的就是 int8_t 這樣的表示。
那麼一元運算子是什麼意思呢?
int i = ~k; //操作是數只有自己啊
int i = a&b; //這樣才是二元
按位很好理解就是每一位都操作一下,比如 a =0b11111001 b=0b00001110
例子:a & b
1111 1001
& 0000 1110
----------------
0000 1000
這四個符號的優先順序:~ & ^ |
避免歧義就不要吝嗇括號 ,當然看了半天,想到還有 || && 這個操作是邏輯操作,結果是0 或者1,和這個不太一樣。
1.設定位
2.清楚位
3.測試位
假設我們的乙個8位暫存器儲存在unsigned char x 中。[0-7位]
1.比如說讓乙個數的第四位設定為1。 我們只需把第4位 或(|)上1 即可.
x |= 0b0001 0000
x |= 0x0100
為了更通用的寫法,我們通常把第幾位當成乙個變數i
x |= (1<
2.比如說讓乙個數的第四位清零。 我們只需把第4位 &上0 即可。
x & 0b 1110 1111
x & 0x ef
因為構造某一位為0,我們需要給其他位填充1。我們有一種更通用的做法。
~0 便是0xfffffffffffffffff 位數就看變數的型別了,跳一步直接用i表示,我們可以得出下面的式子
x &= ~ 0x0010
x &= ~ (1<
3.測試第4位是否為1
if( x & 0x0010 )
==>
if( x & (1<
#define getbit(dat,i) ( (dat)&( 0x1<<(i) )?1:0 )
#define setbit(dat,i) ( (dat)|=( 0x1<<(i) ) )
#define clearbit(dat,i) ( (dat)&= ~( 0x01<<(i) ) )
這裡沒有考慮dat是什麼型別,可以c語言的關鍵字獲取到型別後,強轉一下,效果應該更好。
extern __inline__ int set_bit(int nr,long * addr)
假設*addr = 0, nr = 3;則執行結果為1000(二進位制數)
(1)如果nr大於32,則addr移動(nr/32)位數,指向下乙個long 的開始位。nr>>5也就是nr除以2的5次方,等於nr/32.
(2)擷取nr的低5位,然後將1左移(低5位對應的10進製數)。這樣做是為了解決當nr大於31時,將1左移32位或者更多將會導致溢位(因為mask是int型,而int型在linux中是32位長)。
為什麼特意擷取nr的低5位呢,我認為是經驗,你可以試試看,比如我傳遞給nr的值為33,則mask的值為
mask = 1 << (33 & 0x1f); 計算結果為mask=1<<1,mask=0x10,
另外說明一下:
0x1f(16進製制) = 11111(2進製) = 31(10進製)
對於1.2兩部非常的佩服,統一了是否移位大於32位的操作
感覺指標運用的爐火純青,關於x位處理器long的實現應該是x位吧。
通過步驟1我們知道addr指向32位的位置,那麼 (
*addr |= mask
)就會把第33位置1了。
首先用按位與清除
使用按位或存入
比如將101(0x5) 存入 4-6位
i=(i & ~0x70 )|( 0x5 >>4)
這裡還需要歸納一下 0x70 因為是清理3位 那麼 0x7左移動4位
i= (i & ~(0x7 >>4) | 0x5 >>4)
那麼我們只需要清理幾位,放到第幾位(最低位),和存入的值 即可。
#define setnbit(dat,n,low_index,value) \
(dat) = ( (dat) & ~( mask <<(low_index) ) | ((value) <<(low_index)) ); \
}
例:獲取 3-5位
移位到最位數最右端,然後取n位
( i >>3 ) &0x7
#define getnbit(dat,n,low_index,value)\
value = ( (dat)>>(low_index) &(mask) );\
}
感覺這種巨集的實現有點蹩腳,還是用函式實現比較看起來爽一點。
void setnbit(unsigned *dat, int n, int low_index, int value)
*dat = *dat & (~(mask << low_index)) | (value << low_index);
}void getnbit(unsigned *dat, int n, int low_index, int *value)
*value = (*dat >> low_index) & mask;
}
C語言位操作
在電腦程式中,資料的位是可以操作的最小資料單位,理論上可以用 位運算 來 完成所有的運算和操作。一般的位操作是用來控制硬體的,或者做資料變換使用,但是,靈活的位操作可以有效地提高程式執行的效率。c語言提供了位運算的功 能,這使得c語言也能像組合語言一樣用來編寫系統程式。位運算子c語言提供了六種位運算...
c語言位操作
位運算 and與 有一位為0 運算就為0 想獲取高四位,a a 0xf0 簡寫 a 0xf0 清零 一三五七位清零 a a 0x55 檢測位 檢測第三位 a a 0x04 遮蔽高四位,保留低4 位 a a 0x0f 統計2進製a中1的個數 1 include2 int main 3 11 print...
C語言位操作
朱老師物聯網大講堂 學習筆記 1 位與 只有1 1才是1,其餘全是0,位或 只有0 0才是0,其餘全是1,位取反 按位操作,位異或 1 0 1 0 1 1,也就是說相異結果是1,與1異或會取反,與0異或無變化,移位分 左 右 移,物件分 有 無符號數,只說一點 有符號數右移左側補符號位,叫算術移位,...