前言
bitwise operation 對於 ic 韌體設計,以及 embedded system 的韌體設計,都是一個非常重要的存在
為了節省空間,通常一個晶片的數值空間中,每一個 bit 都會代表一個功能,此時如果我們要設定該功能的時候,就不能單單直接 assign 一個數值,這樣可能會更動到其他的 bit 使得其他功能被你更動
因此才衍伸出「bitwise operation」這種程式方式,學習此技能後,對於 embedded linux / bare-metal / MCU / SoC register 的設定方式都會更容易了解
在此收集了一些有趣的問題,並且練習一下
取一個 8bit 數值的最高位元位置
使用二分法
1 | int get_highest_bit_position(unsigned char x) |
取一個 8bit 數值的最低位元位置
最低位元,很有趣,使用 2’s compliment 就可以完成,比如說1
2
3
4
5
6
70x34
0011 0100
2's 1100 1011 + 1
& 1100 1100
---------------------
0000 0100 ---------> result
這時候我們再用剛剛的找最高位元找出答案就可以了
1 | int get_lower_bit_position(unsigned char x) |
取出一個 unsigned int
數值中含有 1 個數的總和
我們做個比方好了1
2
3
4
5
6
7
80x5a5a
0101 1010 0101 1010
- 1
------------------------------
0101 1010 0101 1001
& 0101 1010 0101 1010
------------------------------
0101 1010 0101 1000
這樣就會消除最低 bit
之後我們繼續做,就可以消除倒數第二的 bit,以此類推
1 | int numbers_of_1_in_int(unsigned int x) |
如何偵測這個數值是 2 的 n 次方?
簡單說 2 的 n 次方,可以認為是「在這個數值中,bit 中含 1 的個數為 1」
因此可以寫成
1 | bool is_nth_power_of_two(unsigned int x) |
set bit x
這個就是基本題了,使用 or gate 就可以了
1 | unsigned int set_bit(unsigned int x, int bitnum) |
當然簡化寫法就是 x |= 1<<bitnum
clear bit x
這個也是基本題
做個比方
0x43 清掉 第 6 個 bit
1 | 0x43 |
所以答案就是1
2
3
4
5unsigned int clear_bit(unsigned int x, int bitnum)
{
x = x & ~(1<<bitnum);
return x;
}
也可以寫成 x &= ~(1<<bitnum)