1. 程式人生 > 其它 >原碼、反碼、補碼以及java位運算(轉載)

原碼、反碼、補碼以及java位運算(轉載)

轉載自:https://www.cnblogs.com/findbetterme/p/10787118.html (若有冒犯,評論立刪)

一、前言

在計算機二進位制中bit(位 簡稱b或位元)是資料儲存的最小單元,每個二進位制數由01組成,每一個數字就是一位bit,其中每8bit = 1 byte(位元組)

java中的基本資料型別

資料型別 所佔位元組數 所佔位數
byte 1 byte 8 bit
short 2 byte 16 bit
int 4 byte 32 bit
long 8 byte 64 bit
float 4 byte 32 bit
double 8 byte 64 bit

二、符合位

二進位制數最高位為符合位,整數又分為正數和負數,正數為無符號位(最高位為0),負數為有符合位(最高位位1)

譬如:

5 ---> 二進位制數:00000000 00000000 00000000 00000101

-5 ---> 二進位制數:10000000 00000000 00000000 00000101

三、原碼、反碼、補碼

3.1 原碼

原碼就是該數字不進行其他操作,數字最原始的二進位制表示,在java中,對於整數而言,其原碼格式為最高位為符號位,該位上1表示負數,0表示正數,剩餘位數為該數字的二進位制表示

對於原碼取絕對值,只有符號位發生改變,其他位不變(若符號位為1,取絕對值後為0)

3.2 反碼

正數的反碼:正數原碼

負數的反碼:負數原碼除符號位以外的位數取反(若為0則改為1,若為1則改為0)

3.3 補碼

正數的補碼:正數原碼

負數的補碼:負數反碼後加1(-b = ~b + 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。

五、位運算子

5.1 & 按位與

規則:兩個數的二進位制數中,只有兩個數對應的二進位制位數同為1時,結果為1,反之為0,對應位數同為0時,結果為0,反之為1

5.2 | 按位或

規則:兩個數的二進位制數中,只有兩個數對應的二進位制位數同為0時,結果為0,對應的位數同為1時,結果為1,其餘結果都為1

5.3 ~ 按位非

規則:單目運算子,該數值的二進位制數除符號位以外都取反

正數取反為負數,比原值小1 負數取反為整數,比原值小1 可以用該特徵求絕對值

5.4 ^ 按位異或

規則:兩個數的二進位制數中,只有兩個數對應的二進位制位數相同時(同為1或0),結果為1,否則其餘結果都為0

5.5 << 左位移

規則:數值的二進位制位數向左移動,符號位不變,低位補0;如:2<<2結果為8

當移動的位數超過數字本身的位數時,那麼不就都需要補0操作,實際上不是的,java不可能做那麼浪費資源的事情。在真正執行位移前,其對要移動的位數做了一些預處理,比如32處理為0,-1處理為31

左移幾位,相當於乘與2的幾次冪

5.6 >> 右位移

規則:數值的二進位制位數向右移動,如果該數為正數,則高位補0,若為負數,則高位補1;如:-6>>2結果為-2

右移幾位,相當於除以2的幾次冪

5.7 >>> 無符號右移

規則:數值的二進位制位數向右移動,也叫邏輯右移,即若該數為正,則高位補0,若該數為負數,則右移後高位同樣補0(注意,無符號右移(>>>)中的符號位(最高位)也跟著變,無符號的意思是將符號位當作數字位看待)