**:
位是資料儲存的最小單位。
在計算機中的二進位制數系統中,位,簡記為b,也稱為位元,每個0或1就是乙個位(bit)。
我們先來看看位運算操作符:& (按位與)、| (按位或)、^ (按位異或)、~ (按位取反)、>> (按位右移)、<< (按位左移)。
1、&(按位與)
從概念上來講,就是將參與運算的兩個分量對應的每一位來做邏輯與運算,若兩者都為真(等於1),則結果才為真(等於1)。否則都為假(等於0)。
即:
1 & 1 =1
1 & 0 = 0
0 & 1 = 1
0 & 0 = 0
這裡我們先來看看那乙個8位二進位制的例子:
7&8 =0000 0111 & 0000 1000 = 0000 0000 = 0
7&6 = 0000 0111 & 0000 0110 = 0000 0110 = 6
2、| (按位或)
即把參與運算的每個分量對應的每一位來做邏輯或運算,即兩者都為假(為0)時,才為假(為0),否則皆為真。
即:
0
|0 = 0
1|0 = 1
0|1 = 1
1|1 = 1
來看看8位二進位制的例子:
7
|8 = 0000 0111 | 0000 1000 = 0000 1111 = 15
7|6 = 0000 0111 | 0000 0110 = 0000 0111 = 7
3、^(按位異或)
即把參與運算的每個分量對應的每一位來做異或運算,即兩者相同為假,不同為真。
即:
0
|0 = 0
1|0 = 1
0|1 = 1
1|1 = 0
看下面的例子:
7^8
= 0000
0111
^ 0000
1000
= 0000
0111= 7
7^6= 0000
0111
^ 0000
0100
= 0000
0011= 3
4、~(按位取反)
即把二進位制位的每一位進行取反運算,簡而言之就是1變成0,0變成1。
直接看例子:
~7 =~0000 0111 = 1111 1000 = 248
5、 >>(按位右移)把二進位制位整體向右移動
7>>1 =0000 0111 >> 1 = 0000 0011 = 3
7>>2 = 0000 0111 >> 2 = 0000 0001 = 1
這裡右移等於除了2的n次方,n為右移的位數。
6 <<(按位左移)這裡就不詳細說了,和右移相反。
位操作應用
一、一種顏色的表示方式—- 通過dword來表示顏色
定義:
typedef
unsigned
long dword;
即為乙個無符號32位(32機器)長整數,有四個位元組,我們從左到右叫他1,2,3,4位元組,每乙個位元組的範圍是0~255。第乙個位元組表示alpha值,即透明度。如果是255,表示不透明,0表示完全透明(
看不到),其他分別是r,g,b值。
可通過下列方法獲得每個位元組的值:
int a = (int)((dword & 0xff000000) >> 24);
int r = (int)((dword & 0x00ff0000) >> 16);
int g = (int)((dword & 0x0000ff00) >> 8);
int b = (int)(dword & 0x000000ff);
dword dwcolor = (a<<24)+(r<<16)+(g<<8)+b;
有了前面的基礎,我相信大家對上面的換算方法,一看就明白吧。如果對16進製制不敏感的童鞋,可以用計算機把十六進製制換算成二進位制,更容易理解。
二、狀態系統中的使用
在遊戲開發中,我們通常用乙個32位(假設這裡用32位)的整數來儲存角色的狀態(這樣做主要是為了節約儲存空間,同時也減小網路同步訊息包的size)。所謂的狀態,就是大家熟悉的buff或者debuff。
enum
role_status
;
狀態資料定義好了,現在來看看怎麼使用他們。
首先, 角色上線,我要給他乙個保護狀態,應該這樣操作。
dword dwrolestatus =status_god;
同時,角色使用了乙個物品,這個物品的效果時,hp和mp上限增加一段時間。因此要附加調整玩家的hp和mp上限的狀態,應該這樣。
dword dwrolestatus |=(status_maxhp_adjust+status_maxmp_adjust);
這裡是|=而不是=操作,因為不能清掉之前附加的無敵保護狀態。所以用或運算。
該角色受到其他玩家或者怪物的攻擊,我們要判斷被攻擊的這個角色的受保護狀態狀態還在不在。執行如下邏輯
if( dwrolestatus & status_god ) // 判斷位是否為1
接下來,角色無敵保護時間過期了,我們要清除無敵狀態,執行如下操作
dwrolestatus &=~status_god;
這裡用到了取反的計算。~status_god的結果是第二位為0外,其他都為1。然後和dwrolestatus做按位與計算。
status_god 等於 0000 0000 0000 0000 0000 0000 0000 0000 0000 0010;
~status_god 等於 1111 1111 1111 1111 1111 1111 1111 1111 1111 1101;
因此和dwrolestatus相與之後,dwrolestatus除了第二位以外的位,都保留下來了。第二位不管是什麼值,都會被設定為0,這樣子就把status_god這個狀態清除掉了。同理我們要清除多個狀態的時候,先把要清楚的狀態或運算到一起。再取反,然後和dwrolestatus按位與。起到同時清除多個狀態。
然後講講異或,它有乙個性質是,兩次異或,能還原回來
例如
a=7,b=6
;a = a^b^b
我們來看看那二進位制的操作
a = 0111
b = 0110
c = a^b = 0001
a = c^b = 0111
寫到這裡,想到一道經典的c++筆試題,即不需要第3個變數,交換兩個變數的值。
a = a^b = 0001
b = b^a = 0111
a = a^b = 0110
暫時寫到這裡,想到有補充的,再完善。
瘋刀 2011.6.26
C 位運算詳解
以前收藏過一篇講c 位操作的文章,這次部落格搬家,以前的資料都沒有保留,整理谷歌 管理後台的時候,發現不時的還有有在查詢這篇文章。所以,瘋刀也來弄個簡單的教程,講講位操作的用途和魅力吧。位是資料儲存的最小單位。在 計算機中的二進位制數系統中,位,簡記為b,也稱為位元,每個0或1就是乙個位 bit 我...
C 位運算詳解
位是資料儲存的最小單位。在 計算機中的二進位制數系統中,位,簡記為b,也稱為位元,每個0或1就是乙個位 bit 我們先來看看位運算操作符 按位與 按位或 按位異或 按位取反 按位右移 按位左移 1 按位與 從概念上來講,就是將參與運算的兩個分量對應的每一位來做邏輯與運算,若兩者都為真 等於1 則結果...
C 位運算詳解
運算子 描述 位與 當兩個二進位制操作位都為1時,結果就為1 位或 當兩個二進位制操作位有1個為1時,結果就為1 位異或 當兩個二進位制操作位只有1個為1時,結果為1 位非 操作位的每個位都取反 就是0變成1,1變成0 二進位制左移運算子。左運算元的值向左移動右運算元指定的位數。右移 二進位制右移運...