C 位運算詳解

2021-07-11 14:57:33 字數 3731 閱讀 9915

**:

位是資料儲存的最小單位。

在計算機中的二進位制數系統中,位,簡記為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 二進位制左移運算子。左運算元的值向左移動右運算元指定的位數。右移 二進位制右移運...