C# Online ! 第十七篇:C# 運算子來嘍 Part IV 『逐位運算子』

  • 16573
  • 0
  • C#
  • 2011-07-08

C# Online ! 第十七篇:C# 運算子來嘍 Part IV 『逐位運算子』

大家好! 這次要介紹的是『逐位運算子』,什麼叫做逐位運算子呢? 簡單的說,就是把第一個運算元的每一個位元與第二個運算元的每一個位元做逐一比對,第一個位元對第一個位元、第二個位元對第二個位元...,再來就是把運算子套用到每一對位元,而運算結果以位元構成(所以也有人稱為位元運算子)。

舉例來說,像是在第十五篇布林邏輯所介紹到的 & 與 | 運算子,& 會針對其運算元進行邏輯位元 AND 運算。而 | 會針對其運算元進行位元 OR 運算,以下用表格的方式來表現,大家應該會比較容易理解:

 

第一個運算元的每一個位元

第二個運算元的每一個位元

& 運算後的結果

1

1

1

1

0

0

0

1

0

0

0

0

(每一對位元都會去做AND運算)
 
 
 

使用 | 運算子的時候也是,當然比較出來的結果會跟 & 不一樣,如下表:

 

第一個運算元的每一個位元

第二個運算元的每一個位元

| 運算後的結果

1

1

1

1

0

1

0

1

1

0

0

0

(每一對位元都會去做OR運算)
 
 
 

舉個例子,一起思考看看運算後的結果吧:

 

int result, op1, op2;
op1 = 4;
op2 = 5;
result = op1 & op2;

 

依照這個例子,我們要用 & 運算的時候,必須要先把數值用二進位來表示,所以 op1 的值換成二進位以後,就是 100,而 op2 則是101,接下來我們就可以開始用&運算,運算的方式如下:

  1. 從最左邊的位元開始 & 運算,也就是說,如果 op1 最左邊的位元為 1 ,op2 的最左邊位元也為 1 ,那運算結果就為 1 ,否則為 0。
  2. 換下一個位元做 & 運算,如果 op1 的位元為1 ,op2 也為1 ,運算結果就為 1,否則為 0。
  3. 再換下一個位元做 & 運算,以此類推 .....

現在把 op1 的每一個位元跟 op2 的每一個位元來做 & 運算,最左邊的位元皆為 1,所以結果是1 ,第二個位元都是 0 ,所以結果是 0,第三個位元分別是 0 跟 1,所以結果是 0,最後算出來的值為二進位的 100,算到這邊就可以知道最後 result 的值為 4,再用運算式方式來表現給大家看,應該會更清楚:

    ch17-01

 

我們也可以將以上這個例子的運算子換成 | ,其結果就會不同,使用 | (OR) 運算,只要每一對位元之中有一個為 1,運算結果則為 1,否則都是 0,以運算式表現給大家看:

ch17-02

用 | (OR) 去運算以後,最後 result 的值為 5。

 

我們也可以使用 ^ (XOR) 運算子,他也是會逐位的用 ^ 去運算結果,每一對位元中要有其中一個為1(不能兩個都是1),否則為 0 ,用表格的方式來表示:

 

第一個運算元的每一個位元

第二個運算元的每一個位元

^ 運算後的結果

1

1

0

1

0

1

0

1

1

0

0

0

(每一對位元都會去做XOR運算)
 
 

C#中也允許用一元的逐位運算子( ~ ),~ 運算子會在運算元上執行反轉每個位元的位元補數運算。會預先定義 int、uint、long 和 ulong 的位元補數運算子。二進位的運算如下表:

 

運算元的每一個位元

~ 運算後的結果

1

0

0

1

 
~ 運算子又被稱為取補數,比較常見的例子是 ~1 = –2,也就是 1的補數是-2 ,補數也許有點難理解,可以直接記成它會把運算元的每一個位元反轉,也就是把1變成0,把0變成1,根據小弟研究後的結果,其實補數就是 (~x+1) = (-x) ,例如 2 的補數為 - 3,3 的補數為 -4,以此類推。
 
除了以上介紹的4個逐位運算子,另外還有兩個,這兩個也被稱為移位運算子,如下表所示:

 

運算子

名稱

類型

說明

例子

結果

>>

向右移位運算子

(Right-Shift)

Binary

( 二元運算子 )

(>>) 會將第一個運算元向右移動,移動的位元數由第二個運算元所指定。第二個運算元的型別必須是 int。(將運算元右移,左邊補0)

var1 = var2 >> var3;

var1的值為var2右移var3的位元數後的值。

<<

向左移位運算子

(Left-Shift)

Binary

( 二元運算子 )

 

(<<) 會將第一個運算元向左移動,移動的位元數由第二個運算元所指定。第二個運算元的型別必須是 int。(將運算元左移,右邊補0)

var1 = var2 << var3;

var1的值為var2左移var3的位元數後的值。

如果第一個運算元是 intuint (32 位元的個數),第二個運算元的低序位五個位元就會提供移位計數。

若第一個運算元是 longunlong (64 位元的個數),則第二個運算元的低序位六個位元會提供移位計數。

 
 
 
 
舉個例子會更容易了解,看以下的例子:

 

int var1, var2 = 10, var3 = 2;
var1 = var2 << var3;

 

 
以上我們可以這樣運算,var2 = 10,換算成2進位為 1010,var3 = 2,所以要左移2位元,右邊補 0,結果為 101000,var1的值為 40。實際上用數學公式來說的話,我們等於是做了乘法,每左移一個位元,就會乘2,所以var2 = 10,var3 = 2 , 10 x 2 x 2 = 40 ,這樣有比較清楚了嗎?  
 
反過來說,右移的時候,就是每右移一個位元,就會除以2,取商數,餘數則捨去,可以看以下的例子:

 

int var1, var2 = 10;
var1 = var2 >> 1;

 

 
以上的運算的結果 var1 為 5。10/2 = 5 ,var2 = 10,換算成二進位為 1010,右移1位元,左邊補後為 0101,結果var1 為5。
 
最後再介紹兩個位移指派運算子,<<= 與 >>=,如下表所示:

 

運算子

名稱

類型

說明

例子

結果

>>=

右移指派運算子
(Right Shift)

Unary

( 一元運算子 )

將第一個運算元向右移動,移動的位元數由第二個運算元所指定。第二個運算元的型別必須是 int。(將運算元右移,左邊補0)

var1 >>= var2;

就像 var1 = var1 >> var2,與使用 >> 不同的地方在於使用>>=時, var1只會被評估一次。

<<=

左移指派運算子
(Left Shift)

Unary

( 一元運算子 )

將第一個運算元向左移動,移動的位元數由第二個運算元所指定。第二個運算元的型別必須是 int。(將運算元左移,右邊補0)

var1 >>= var2;

 

就像 var1 = var1 << var2,與使用 << 不同的地方在於使用<<=時, var1只會被評估一次。

 

這次又介紹了不少運算子,剛起步的初學者們也許會覺得很複雜,不過好好的運用這些運算子,對於往後我們在寫程式的時候,幫助非常的大,特別是因為它們可以優化我們的程式,可能有些程式本來得寫幾十行,可以縮減成幾行內就搞定,當然還要靠許多實作經驗的累積,我們一起加油吧!

 

希望資深的前輩們與跟我一樣剛開始想學習C#的初心者,可以給我一些建議跟鼓勵,或是幫我按個讚!您的鼓勵就是我的動力! 感謝您們 ~

(本文中相關內容有參閱、引述MSDN)

 

 

 

 


如果這篇文章對您有幫助,請幫我點選「我要推薦」、按個讚、或是幫我推到其他平台;您的鼓勵將會是我繼續努力的一大動力!!

若是有任何指教或是需要討論之處,也不用客氣,請在下面留言給我,我將會儘速回覆~

Share | . . . . . . . . . .