1. 程式人生 > >二進位制原碼、反碼、補碼以及Java中的<< 和 >> 和 >>> 詳細分析

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

## 1、計算機二進位制系統中最小單位bit > 在計算機二進位制系統中: > bit (位) :資料儲存的最小單元。 簡記為`b`,也稱為位元(`bit`),每個二進位制數字0或1就是一個位(`bit`),其中,每 `8bit = 1 byte`(位元組); > 再回顧Java 中的資料型別,如`int資料型別 = 4個byte(位元組)`,而`1 byte(位元組) = 8 bit(位)`;也就我們常說的`int = 32位`(說白了,在二進位制系統中是以bit 作為資料儲存單元的)。如下 ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200304150230731.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NTQzNTA4,size_16,color_FFFFFF,t_70) ## 2、有符號數和無符號數 有符號數和無符號數簡單的說就是分別對應正數和負數,在二進位制系統中是以bit(位)來作為資料儲存單元的,**最高位(第一位)是符號位,正數符號位為“0” ,負數符號位為“1” 。** 例子: 假設 `int number = 1` ,那麼number在計算機系統中將表示如下: 00000000 00000000 00000000 00000001 同理可得,`number = -1` 時,在二進位制中表示如下: 10000000 00000000 00000000 00000001 > 注意:最高位(第一位)是符號位,因為是number值為1是一個正數,所以最高位為0; ## 3、二進位制的原碼、反碼、補碼 **原碼** 原碼就是機器數,是加了一位符號位的二進位制數(因為數值有正負之分),正數符號位為0,負數符號位為1。 **反碼** 帶符號位的原碼乘除運算時結果正確,而在加減運算的時候就出現了問題,比如: 用十進位制表示:`1 + (-1) = 0`, 但用二進位制表示: 00000001 + 10000001 = 10000010, 將結果換算成十進位制數也就是 -2。於是在原碼的基礎上發明了反碼,用來解決這種問題。 **補碼** 雖然反碼的出現解決了正負數的加減問題, 但卻讓0這個數字有了兩種"形態": "0"和"-0", 但這是不合邏輯的,只應該有一個0,所以出現了補碼。 **對於有符號數而言**: >1、正數的原碼、反碼、補碼都一樣; 2、負數的反碼 = 它的原碼符號位不變,其他位取反(取反的意思:0 換成 1 、 1 換成 0 ); 3、負數的補碼 = 它的反碼 +1; 4、0的反碼、補碼都是0; **【特別注意】 1、在計算機運算的時候,都是以 補碼 的方式來運算的 。 2、二進位制 轉為 十進位制,必須使用 二進位制 的原碼進行轉換 。** ### 例子: 下面我們就使用“有符號數”來模擬一下,在計算機中是怎樣運算的。 **(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 ## 4、思考: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. ## 5、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車,咋們走!最主要的是一起探討技術,嚮往技術,追求技術,說好了來了就是盆友喔... ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/2019112519430061.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NTQzNTA4,size_16,color_FFFFFF,t_70) 參考: https://www.cnblogs.com/summerdata/p/10722359.html https://www.cnblogs.com/chuijingjing/p/9405