1. 程式人生 > >C語言位運算子及作用:與、或、異或、取反、左移和右移

C語言位運算子及作用:與、或、異或、取反、左移和右移

一、& 按位與

如果兩個相應的二進位制位都為1,則該位的結果值為1,否則為0
應用:
(1)清零
若想對一個儲存單元清零,即使其全部二進位制位為0,只要找一個二進位制數,其中各個位符合一下條件:
原來的數中為1的位,新數中相應位為0。然後使二者進行&運算,即可達到清零目的。
a 00101011
b 10010100
c 00000000 //c = a & b

(2)取一個數中某些指定位
若有一個整數a(2byte),想要取其中的低位元組,只需要將a與8個1按位與即可。
a 00101100 10101100
b 00000000 11111111
c 00000000 10101100 //c = a & b

(3)保留指定位:
a 01010100
b 00111011
c 00010000 //c = a & b

二、| 按位或
兩個相應的二進位制位中只要有一個為1,該位的結果值為1。借用邏輯學中或運算的話來說就是,一真為真
應用:將一個數據的某些位定值為1
a 00110000
b 00001111
c 00111111 //c = a | b

三、^ 按位異或
若參加運算的兩個二進位制位值相同則為0,否則為1
應用:不用臨時變數,交換兩個值

計算前:
a=3,即011(2);b=4,即100(2)

計算過程:
a=a ^ b; //即111 = 011 ^ 100
b=b ^ a; //即011 = 100 ^ 111
a=a ^ b; //即100 = 111 ^ 011

計算後:
a=100(2)即 4 ;b = 011(2)即 3;

四、~ 取反
~是一元運算子,用來對一個二進位制數按位取反,即將0變1,將1變0

五、<< 左移
用來將一個數的各二進位制位全部左移N位,右補0

六、>> 右移
將一個數的各二進位制位右移N位,移到右端的低位被捨棄,對於無符號數,高位補0

七、原碼, 反碼, 補碼的基礎概念和計算方法
在探求為何機器要使用補碼之前, 讓我們先了解原碼, 反碼和補碼的概念《雜諞桓鍪? 計算機要使用一定的編碼方式進行儲存。原碼, 反碼, 補碼是機器儲存一個具體數字的編碼方式.

(1)原碼
原碼就是符號位加上真值的絕對值, 即用第一位表示符號, 其餘位表示值.

比如如果是8位二進位制:

[+1]原 = 0000 0001
[-1]原 = 1000 0001

第一位是符號位. 因為第一位是符號位, 所以8位二進位制數的取值範圍就是:
[1111 1111 , 0111 1111] 即 [-127 , 127]

原碼是人腦最容易理解和計算的表示方式。

(2)反碼
反碼的表示方法是:

正數的反碼是其本身
負數的反碼是在其原碼的基礎上, 符號位不變,其餘各個位取反.

[+1] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反

可見如果一個反碼錶示的是負數, 人腦無法直觀的看出來它的數值. 通常要將其轉換成原碼再計算.

(3)補碼
補碼的表示方法是:

正數的補碼就是其本身
負數的補碼是在其原碼的基礎上, 符號位不變, 其餘各位取反, 最後+1. (即在反碼的基礎上+1)

[+1] = [00000001]原 = [00000001]反 = [00000001]補
[-1] = [10000001]原 = [11111110]反 = [11111111]補

對於負數, 補碼錶示方式也是人腦無法直觀看出其數值的. 通常也需要轉換成原碼在計算其數值.

計算機中帶符號的整數為何採用二進位制的補碼進行儲存

二、編碼

計算機使用補碼錶示負整數!正整數就用原始碼來表示。那什麼是補碼呢?其實原始碼的補碼就是原始碼的相反數他們相加得0 。

計算負整數的補碼:

規則就是原始碼各位取反,然後加1得到。

例如:如果我們用8位來表示有符號整數的話,那麼十進位制1用二進位制表示為:

  1. 00000001  
00000001
這個數取反加1的結果是:
  1. 11111111  
11111111

所以,-1的補碼就是11111111。

大家可能會有疑問,到底什麼是補碼,為什麼-1的補碼不是-1的原始碼取反加1呢?

這是因為:-1的補碼是1的補碼錶示法。所以計算機裡用1的相反數(就是-1的補碼)來表示-1 。

計算二進位制有符號數的十進位制數(負二進位制---10進位制) 取反加1加負號

既然有符號數在計算機裡有補碼錶示負整數,那我們如何根據給定的二進位制數來計算十進位制數呢?

看例子:

假設給了一個數:10000100  

符號位為1,為負數,所以這個數是用補碼錶示的!先計算原始碼。

各位取反加1的結果是:01111100(二進位制) = 124(十進位制)  

01111100(二進位制) = 124(十進位制)

所以原先給出的二進位制數的十進位制數是 -124 。

計算負整數的二進位制補碼錶示(負10進位制--2進位制) 計算正二進位制 取反加1

繼續剛才那個例子,如果我們拿到的是十進位制-124,那麼他的二進位制補碼是多少呢?

其實他的補碼就是124的二進位制數求補的結果。

124的二進位制數為:01111100

取反                       :10000011

加1                         :10000100

所以-124的二進位制補碼錶示就是10000100

為什麼使用補碼錶示負整數

原因很簡單,如果使用補碼錶示負整數,那麼ALU在做整數之間的操作時,就不用區分符號了,所有位都會參與運算,其上上面的例子中,符號位都參與了運算。

例如執行2-1這個操作,我們可以用2+(-1)來計算。

2的二進位制數是:00000010

1的二進位制數是:00000001   -->   -1的二進位制補碼是:11111111

所以2+(-1):

[cpp] view plaincopyprint?
  1.   00000010  
  2. + 11111111  
  3. ----------------  
  4.   00000001  
  00000010
+ 11111111
----------------
  00000001

結果是1。

我們再看個結果為負數的。

求1-2的結果,用1+(-2)來計算。

2的二進位制數是:00000010,所以-2的二進位制數為:11111101+1=11111110

1+(-2)的計算過程是:

[cpp] view plaincopyprint?
  1.   00000001  
  2. + 11111110  
  3. ---------------  
  4.   11111111  
  00000001
+ 11111110
---------------
  11111111

這個結果的十進位制數是多少呢?

首先它是個負數,說明結果使用補碼錶示的,將各位取反加1後的結果是00000001=1(十進位制),然後加上他的符號,就是-1了,

所以1+(-2)的結果是-1 。

用補碼計算確實簡化了ALU的設計難度!!所以計算機用補碼來表示負整數!!!!

(負二進位制---10進位制) 取反加1加負號

負10進位制--2進位制) 計算正二進位制 取反加1(正數的相反數)