[C][Bit-Operator] Bitwise operator

Review and illustrate 位元運算

  • 位元運算可以運用在很多地方: 乘法, 除法, 功能指派, 判斷位元, 數值交換 …
  • 符號 " << " 跟 " >> "
    • 分別表示 " << 位元左移 " 跟 " >> 位元右移 "
    • 在十進位數中, 當全部位元向左移動一格時, 數值會變成原來的十倍
      • Ex: 123 全部向左移動一格 => 1230
    • 在二進位數中, 也有相同的特性, 當全部位元向左移動一位元, 會變成原來的2倍, 反之向右移動一位元時, 會變成原來的 ½ 倍
    • 如下圖可以推論出, 向右1位元即是原數值的2倍, 向右2位元即是原數值的2^2倍 and stuff…
    • 電腦進行位元運算比乘法, 除法運算快上許多, 所以通常會利用位元運算取代乘法, 除法運算
圖中說明, 6 向左移動一位元, 二位元, 三位元, 以及向右移動一位元的結果

 

  • "&"  AND 邏輯符號
    • &功能是將兩個變數對應的位元進行 AND 邏輯運算, 例如可以用來判斷特定位元是否為1
  • "|" OR 邏輯符號
    • | 功能是將兩個變數對應的位元進行 OR 邏輯運算, 可以用來設定特定位元為1
    •  
  • "^" XOR 邏輯符號
    • 功能是將兩個變數對應的位元進行 XOR 邏輯運算
      • 0 ^ 0 = 0
      • 0 ^ 1 = 1
      • 1 ^ 0 = 1
      • 1 ^ 1 = 0
  • "~" NOT 邏輯符號
    • 功能是顛倒每一個位元.  0→1, 1→0
  • 應用於某個功能的狀態
    • 比方說紀錄一個 dialogue 的狀態, 較直覺但是較不好的方法是, 用多個變數代表不同的狀態; 較好的方式是用1個變數表示不同的狀態
1. 已知有那麼多種狀態
typedef enum
{
	UA_RACE_COND_NONE,
	UA_RACE_COND_SEND_CANCEL = 0x01,
	UA_RACE_COND_SEND_BYE = 0x02,
	UA_RACE_COND_DELAY_BYE = 0x04,
	UA_RACE_COND_LOCAL_HOLD = 0x08,
	UA_RACE_COND_REMOTE_HOLD = 0x10,
	UA_CODEC_CHANGED_G711_FAX = 0X20,
	UA_CODEC_T38_FAX_FAIL = 0x40,
	UA_DLG_INVALID_DLG = 0x80,
	UA_DLG_CALLER = 0x100,
	UA_DLG_DELAY_UNATTEND_XFER = 0x200,
	UA_DLG_UNATTEND_XFER_RING = 0x400,
	UA_RACE_COND_CONNECTED = 0x80000000,
} UA_RACE_COND_T;

// 已知 raceCondFlag 是 dlg 其中的一個變數, 要用此變數表示多種不同的狀態
struct uaDlgObj
{
	UI32_T diallogId;
	UaMgr parent;		        /*keep parent UaMgr object*/
	DxLst txStruct;	            /*transaction list*/
	UACallStateType callState;	/*call state*/
	char *callid;		        /*callid*/
	char *sessid;		        /*callid*/
	unsigned int sdp_sessid;	/*callid*/
 	char *userid;		        /*keep locat user identification*/
	UI32_T raceCondFlag;        /*race condiction for cancel*/
}
2. 通常會寫一個 Function 判斷 dialogue 目前是否屬於特定狀態
BOOL uaDlgGetConnectedFlag(IN UaDlg dlg)
{
	if (dlg)
	{
		if (dlg->raceCondFlag & UA_RACE_COND_CONNECTED)
		{
			return(TRUE);
		}
	}

	return(FALSE);
}

3. 通常會寫一個 Function 標記目前 dialogue 是屬於哪個狀態
RCODE uaDlgSetConnectedFlag(IN UaDlg dlg, IN BOOL flag)
{
	if (dlg)
	{
		if (flag)
		{
			dlg->raceCondFlag |= UA_RACE_COND_CONNECTED;
		}
		else
		{
			dlg->raceCondFlag &= ~(UA_RACE_COND_CONNECTED);
		}
		return(RC_OK);
	}

	return(RC_ERROR);
}
  • 判斷一整數是偶數還是奇數 ?
    • Ans:
  • 判斷一整數是不是2的次方
    • Ans:
  • 交換兩個 int 型態的變數
    • Ans:
  • 計算有幾個位元是1 (指定: 32位元變數)
    • Ans:
  • 顛倒位元順序 (指定: 32 位元變數)
    • Ans: