二進制原碼、反碼、補碼以及Java中的<< 和 >> 和 >>> 詳細分析

一、計算機二進制系統中最小單位bit

在計算機二進制系統中: bit (位) :數據存儲的最小單元。 簡記爲b,也稱爲比特(bit),每一個二進制數字0或1就是一個位(bit),其中,每 8bit = 1 byte(字節);html

再回顧Java 中的數據類型,如int數據類型 = 4個byte(字節),而1 byte(字節) = 8 bit(位);也就咱們常說的int = 32位(說白了,在二進制系統中是以bit 做爲數據存儲單元的)。以下 java

在這裏插入圖片描述

二、有符號數和無符號數

有符號數和無符號數簡單的說就是分別對應正數和負數,在二進制系統中是以bit(位)來做爲數據存儲單元的,最高位(第一位)是符號位,正數符號位爲「0」 ,負數符號位爲「1」 。編程

例子:設計模式

假設 int number = 1 ,那麼number在計算機系統中將表示以下:併發

00000000 00000000 00000000 00000001學習

同理可得,number = -1 時,在二進制中表示以下:ui

10000000 00000000 00000000 00000001設計

注意:最高位(第一位)是符號位,由於是number值爲1是一個正數,因此最高位爲0;code

三、二進制的原碼、反碼、補碼

原碼 原碼就是機器數,是加了一位符號位的二進制數(由於數值有正負之分),正數符號位爲0,負數符號位爲1。cdn

反碼 帶符號位的原碼乘除運算時結果正確,而在加減運算的時候就出現了問題,好比: 用十進制表示:1 + (-1) = 0, 但用二進制表示:

00000001 + 10000001 = 10000010,

將結果換算成十進制數也就是 -2。因而在原碼的基礎上發明了反碼,用來解決這種問題。

補碼 雖然反碼的出現解決了正負數的加減問題, 但卻讓0這個數字有了兩種"形態": "0"和"-0", 但這是不合邏輯的,只應該有一個0,因此出現了補碼。

對於有符號數而言

一、正數的原碼、反碼、補碼都同樣; 二、負數的反碼 = 它的原碼符號位不變,其餘位取反(取反的意思:0 換成 1 、 1 換成 0 ); 三、負數的補碼 = 它的反碼 +1; 四、0的反碼、補碼都是0; 【特別注意】 一、在計算機運算的時候,都是以 補碼 的方式來運算的 。 二、二進制 轉爲 十進制,必須使用 二進制 的原碼進行轉換 。

例子:

下面咱們就使用「有符號數」來模擬一下,在計算機中是怎樣運算的。

(1)正數相加:

例如:1+1 ,在計算機中運算以下:

1的原碼爲:

00000000 00000000 00000000 00000001

由於「正數的原碼、反碼、補碼都同樣」,因此,1的補碼 = 1的原碼,因此 1的補碼+ 1的補碼 就等於:

00000000 00000000 00000000 00000001 + 00000000 00000000 00000000 00000001

=

00000000 00000000 00000000 00000010

00000000 00000000 00000000 00000010( 轉換爲10進制) = 2

(2)正數相減:

例如:1 - 2,在計算機中運算以下:

在計算機中減運算實際上是做爲加運算來操做的,因此,1 - 2 = 1 + ( -2 )

第一步:把 1的補碼找出來(由於正數的原碼、反碼、補碼都同樣,因此咱們可經過原碼直接獲取補碼):

1的補碼:

00000000 00000000 00000000 00000001

第二步:把-2的原碼找出來:

-2的原碼:

10000000 00000000 00000000 00000010

第三步:把-2的反碼找出來:

-2的反碼:

11111111 11111111 11111111 11111101

第三步:把-2的補碼找出來:

-2的補碼:

11111111 11111111 11111111 11111110

第四步:1的補碼與-2的補碼相加:

00000000 00000000 00000000 00000001 + 11111111 11111111 11111111 11111110

=

11111111 11111111 11111111 11111111

第五步:將計算結果的補碼轉換爲原碼,反其道而行之便可(若是想將二進制轉換爲十進制,必須獲得二進制的原碼)

補碼:11111111 11111111 11111111 11111111

=

反碼:11111111 11111111 11111111 11111110

=

原碼:10000000 00000000 00000000 00000001

第六步:將計算結果的二進制原碼 轉換 爲十進制

二進制原碼:10000000 00000000 00000000 00000001 = 1*2^0 = -1

四、思考:java中爲何byte的取值範圍是-128~127

java中byte佔一個字節, 也就是8bit(位), 其中最高位是符號位, 剩下7位用來表示數值.若符號位爲0, 則表示爲正數,範圍爲00000000~01111111(補碼形式),也就是十進制的0-127. 若符號位爲1, 則表示爲負數, 範圍爲10000000~11111111(補碼形式), -128~-1, 11111111轉換爲原碼就是10000001,也就是-1。 在補碼中,爲了不存在"-0",規定10000000爲-128, 因此解釋了byte的取值範圍爲何是-128~127.

五、Java中的<< 和 >> 和 >>>

首先<< 和 >> 和 >>>是java中的位運算符,是針對二進制進行操做的。除了這些還有&、|、^、~、幾個位操做符。無論是初始值是依照何種進制,都會換算成二進制進行位操做。這裏主要講解Java中的<< 和 >> 和 >>>。

<< 表示左移移,不分正負數,低位補0

注:如下數據類型默認爲byte爲8位,左移時無論正負,低位補0

正數:r = 20 << 2

  20的二進制補碼:0001 0100

  向左移動兩位後:0101 0000

       結果:r = 80

負數:r = -20 << 2

  -20 的二進制原碼 :1001 0100

  -20 的二進制反碼 :1110 1011

  -20 的二進制補碼 :1110 1100

  左移兩位後的補碼:1011 0000

        反碼:1010 1111

        原碼:1101 0000

        結果:r = -80

‘ >> ’表示右移,若是該數爲正,則高位補0,若爲負數,則高位補1;

注:如下數據類型默認爲byte爲8位

正數:r = 20 >> 2 

  20的二進制補碼:0001 0100

  向右移動兩位後:0000 0101

       結果:r = 5

負數:r = -20 >> 2 

  -20 的二進制原碼 :1001 0100

  -20 的二進制反碼 :1110 1011

  -20 的二進制補碼 :1110 1100

  右移兩位後的補碼:1111 1011

        反碼:1111 1010

        原碼:1000 0101

        結果:r = -5

‘ >>> ’ 表示無符號右移,也叫邏輯右移,即若該數爲正,則高位補0,而若該數爲負數,則右移後高位一樣補0

注:如下數據類型默認爲int 32位

正數: r = 20 >>> 2

    的結果與 r = 20 >> 2 相同;

負數: r = -20 >>> 2

  -20原碼:10000000 00000000 00000000 00010100

    反碼:11111111 11111111 11111111 11101011

    補碼:11111111 11111111 11111111 11101100

    右移:00111111 11111111 11111111 11111011

    結果:r = 1073741819

最後,如有不足或者不正之處,歡迎指正批評,感激涕零!

歡迎各位關注個人公衆號,裏面有一些java學習資料和一大波java電子書籍,好比說周志明老師的深刻java虛擬機、java編程思想、核心技術卷、大話設計模式、java併發編程實戰.....都是java的聖經,不說了快上Tomcat車,咋們走!最主要的是一塊兒探討技術,嚮往技術,追求技術,說好了來了就是盆友喔...

在這裏插入圖片描述

參考: www.cnblogs.com/summerdata/… www.cnblogs.com/chuijingjin…

相關文章
相關標籤/搜索