2010年4月16日 星期五

位元操作 (Bitwise Operation)

電腦資料都是以二進位儲存,想當然程式語言的變數也都是以二進位儲存。在C/C++當中有幾個位元運算子:<< SHIFT LEFT、>> SHIFT RIGHT、& AND、| OR、^ XOR、~ NOT,可以對變數進行位元運算。
過去寫應用程式時一直都沒太多機會用到,一直到現在開始接觸MCU的程式才開始對位元操作(Bitwise Operation)有些了解. 接下來要介紹位元運算的一些用途,與用法

1.左移 <<

5 << 1 = 10 // 00101 的全部位元向左移動一位數變成 01010.
5 << 2 = 20 // 00101 的全部位元向左移動兩位數變成 10100.
[註]左移和 "乘法" 的概念很像吧.. 事實上應該就是乘法了

2.右移 >> SHIFT RIGHT

5 >> 1 = 2 // 00101 的全部位元向右移動一位數變成 00010。
5 >> 2 = 1 // 00101 的全部位元向右移動一位數變成 00001。
[註]右移和 "除法" 的概念很像吧.. 事實上應該就是除法了

3. 及 & AND
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

4. 或 | OR
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1

5. 互斥 ^ XOR
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0

6. 反向 ~ NOT
~ 0 = 1
~ 1 = 0

==== 上述的內容大部份都可以在書上找到 ====
那麼... 如果是下面的算式結果是如何?
x=5
x&=0x07 ( x = x & 0x07) --> 0x05
x|=0x07 ( x = x | 0x07) --> 0x07

如果再遇到一個... x&= ~0x03 ?
x&=~0x03 其實是 x &= (~0x03) 也等於 x = x & (~0x03)

以上述的列子來說..整個過程大致上是這樣的...
1. (~0x03) 會先做: 指的是將 0b00000011 (0x03) 的bit 0 與 bit 1 做反向
2. 所以結果會變成 0b11111100
3. 然後才又與前的 x &= 做運算

這種用法很常在寫MCU程式時用到.. 做為將某n個位元做ON或OFF的工作..
當然,有沒有好處? 就個人的理解上來看,省了很多變數的使用.. 用bitwise operation就可以達到bit的操作.

寫到這裡讓我想到... 在學校裡好像都不曾聽老師教過.. 這bitwise 到底是要用在哪兒.... :(
這應該又是一個"讀書少" 的例子吧...

http://www.csie.ntnu.edu.tw/~u91029/index.html
這裡可以看到一些很不錯的資料...

沒有留言:

張貼留言