1. 程式人生 > >計算機系統 二進位制原碼 補碼 反碼 詳解 JAVA 二進位制位運算(位與 位或 位取反 位異或 左移 右移)

計算機系統 二進位制原碼 補碼 反碼 詳解 JAVA 二進位制位運算(位與 位或 位取反 位異或 左移 右移)

       在計算機系統中,數值一律使用補碼來表示和儲存。在探求為何計算機要使用補碼之前, 讓我們先了解原碼, 反碼和補碼的概念。

  對於一個數, 計算機要使用一定的編碼方式進行儲存。 原碼, 反碼, 補碼是計算機儲存一個具體數字的編碼方式。

  一個數在計算機中的二進位制表示形式, 叫做這個數的機器數。機器數是帶符號的,在計算機用一個數的最高位存放符號, 正數為0, 負數為1。比如,十進位制中的數 +2 ,計算機字長為8位,轉換成二進位制就是[00000010]。如果是 -2 ,就是 [10000010] 。因為第一位是符號位,所以機器數的形式值就不等於真正的數值。例如上面的有符號數 [10000010],其最高位1代表負,其真正數值是 -2 而不是形式值130([10000010]轉換成十進位制等於130)。所以將帶符號位的機器數對應的真正數值稱為機器數的真值。

  • 原碼就是符號位加上真值的絕對值, 即用第一位表示符號, 其餘位表示值。
  • 反碼的表示方法是:正數的反碼是其本身;負數的反碼是在其原碼的基礎上, 符號位不變,其餘各個位取反。
  • 補碼的表示方法是:正數的補碼就是其本身;負數的補碼是在其原碼的基礎上, 符號位不變, 其餘各位取反, 最後+1。 (即在反碼的基礎上+1)

1、計算機使用補碼的主要原因是使用補碼可以將符號位和其它位統一處理;同時,減法也可按照加法來處理。另外,兩個用補碼錶示的數相加時,如果最高位(符號位)有進位,則進位被捨棄。

- 補碼與原碼的轉換過程幾乎相同。

    - 數值的補碼錶示(分兩種)

        - 正數的補碼:與原碼相同

        - 負數的補碼:符號位位1,其餘位位該數絕對值的原碼按位取反;然後整個數加1

    - 已知一個數的補碼,求原碼的操作分為兩種情況

        - 如果補碼的符號位“0”,表示是一個正數,所以補碼就是該數的原碼

        - 如果補碼的符號位為“1”,表示是一個負數,求原碼的操作可以是:符號位位1,其餘各位取反,然後整個數加1。

2、移位運算子就是在二進位制的基礎上對數字進行平移。Java按照平移的方向和填充數字的規則分為三種:<<左移,>>帶符號右移 和>>>無符號右移。

3、 在Java的移位運算中,byte、short和char型別移位後的結果會變成int型別,對於byte、short、char和int進行移位時,對於char、short、char和int進行移位操作時,規定實際移動的次數是移動次數和32的餘數,也就是移位33次和移位1次得到的結果相同。移動long型的數值時,規定實際移動的次數是移動次數和64的餘數,也就是移動65次移位1次得到相同的結果。

    (1) <<  運算規則:按二進位制形式吧所有的數字向左移動對應的位數,高位移出(捨棄),低位的空位補零。

    語法格式:

         需要移位的數字<<移位的次數

         例如:4<<2 ,則是將數字4左移2位

     計算過程

         4<<2

        Java中一個int數佔四個位元組,那麼4的二進位制數字為00000000 00000000 00000000 00000100,然後把該數字左移兩位。其它的數字都朝右平移兩位,最後在低位(右側)的兩個空位補零。則得到的最終結果是00000000 00000000 00000000 00010000,即轉換為十進位制數16。

         在數字沒有溢位的前提下,對於正數和負數,左移一位都相當於乘以2的1次方,左移n位就相當於乘以2的n次方。

         在溢位的前提前,則不符合這個規律。

    (2)>>運算規則:按二進位制形式吧所有的數字都向右移動對應的位置,低位移出(捨棄),高位的空位補符號位,即正數補零,負數補1。

     語法格式:

         需要移位的數字>>移位的次數

         例如:-4>>2和4>>2,則是將數字 -4和4右移2位

     計算過程

         4>>2

         Java中一個int數佔四個位元組,同樣4的二進位制為00000000 00000000 00000000 00000100,然後把該數字右移兩位。其它的數字都朝左平移兩位,最後在高位補符號位(該數是正數,全補零),得到的結果是00000000 00000000 00000000 00000001,即使十進位制的1。數學意義就是右移移位相當於除2,右移n位相當於除以2的n次方。

        -4>>2

         由於負數在計算機中是以補碼的形式儲存的,那麼-4的二進位制為11111111 11111111 11111111 11111100,然後把該數字右移兩位,其它數字都朝左平移兩位,最後在高位補符號位(該數是負數,全補一),得到的結果是11111111 11111111 11111111 11111111(補碼格式),即是十進位制的-1。

    (3)>>>運算規則:按二進位制形式吧所有的數字向右移動對應的位數,低位移出(捨棄),高位的空位補零。正數運算結果與帶符號右移相同,對於負數來說則不同。

         對於4>>>2和-4>>>2運算,可以通過上述例子進行類推。

4、在java c++ c等程式語言中,二進位制運算主要包括以下幾種:

  • 位與運算子(&)

運算規則:兩個數都轉為二進位制,然後從高位開始比較,如果兩個數都為1則為1,否則為0。

比如:129&128.

129轉換成二進位制就是10000001,128轉換成二進位制就是10000000。從高位開始比較得到,得到10000000,即128.

  • 位或運算子(|)

運算規則:兩個數都轉為二進位制,然後從高位開始比較,兩個數只要有一個為1則為1,否則就為0。

比如:129|128.

129轉換成二進位制就是10000001,128轉換成二進位制就是10000000。從高位開始比較得到,得到10000001,即129.

  • 位非運算子(~)

運算規則:如果位為0,結果是1,如果位為1,結果是0.

  • 位異或運算(^)

運算規則是:兩個數轉為二進位制,然後從高位開始比較,如果相同則為0,不相同則為1。

比如:8^11.

8轉為二進位制是1000,11轉為二進位制是1011.從高位開始比較得到的是:0011.然後二進位制轉為十進位制,就是Integer.parseInt("0011",2)=3;

更高效的判斷奇偶程式:

bool even_odd(int num)
{
    if(((num)>>1)<<1 == num)
        return true;
    return false;
}