1. 程式人生 > >java 補碼實踐

java 補碼實踐

system 進行 由於 -- 的確 結果 sys 二進制 tro

java中的數字都是以補碼的形式出現

java中的byte要轉為數字也是以補碼的形式進行的轉換

=================================================

負數的補碼 = 原碼的符號位不變其余位取反後加一

=================================================

特別的數字
有兩個數字的補碼等於本身:一個是0,另一個為該比特內可表示有符號位區分的二進制形式的最大負數(即1000...)。

0的補碼計算方式(以8位為例)如下:先計算它的反碼:

1111 1111
再將反碼加一:

0000 0000,溢出比特二進制值 = 1(二進制)
忽略溢出,其結果為0(0是唯一計算補碼過程中會出現溢出的數字。)。因此0的補碼為0。而0 x (-1) = 0,因此其補碼仍滿足“數字a的補碼為 -a”的原則。

若計算1000 0000(這是8位內可表示有符號位區分的二進制形式的最大負數-128)的補碼:先計算它的反碼:

0111 1111
再加一就是它的補碼。

1000 0000
1000 0000 (-128)的補碼仍為1000 0000 (-128)。但(-128) x (-1) = 128,因此其補碼是以上規則的例外。

總結:由於0可以等於0的二補數-0,以及同樣因為8位的二補數可顯示的值範圍為 -128 ~ 127,但-128的二補數128無法用在已有比特數量為8的比特數量內的可用二補數表示。【在計算其他位數內的可表示有符號位區分的二進制形式的最大負數(即1000...000)時,也會有類似情形。】

所以:0和-128的確是“數字a的補碼為 -a”原則中兩個特別的數字。

=================================================

// -128原碼:1000 0000 0000 0000 0000 0000 1000 0000
// -128反碼:1111 1111 1111 1111 1111 1111 0111 1111
// -128補碼:1111 1111 1111 1111 1111 1111 1000 0000
System.out.println(Integer.toHexString(-128));
// ffffff80

// (-128 & 0xFF)補碼:
1111 1111 1111 1111 1111 1111 1000 0000
& 0000 0000 0000 0000 0000 0000 1111 1111
= 0000 0000 0000 0000 0000 0000 1000 0000
System.out.println(Integer.toHexString(-128 & 0xFF));


// 00000080

// byte byte_128 = (byte) -128 ( --> -128補碼保留最後8位 --> 1000 0000 )
// byte_128補碼:1000 0000
// byte_128反碼:1111 1111 ( 符號位不變其余位取反 )
// byte_128原碼:1000 0000 ( 補碼取原碼 = 補碼的補碼 )
System.out.println(byte_128);
// -128

// byte byte128 = (byte) 128 ( --> 128補碼保留最後8位 --> 1000 0000 )
// byte128補碼:1000 0000
// byte128反碼:1111 1111 ( 符號位不變其余位取反 )
// byte128原碼:1000 0000 ( 補碼取原碼 = 補碼的補碼 )
System.out.println(byte128);
// -128

// byte byte233 = (byte) 233 ( --> 233補碼保留最後8位 --> 1110 1001 )
// byte233補碼:1110 1001
// byte233反碼:1001 0110 ( 符號位不變其余位取反 )
// byte233原碼:1001 0111 ( 補碼取原碼 = 補碼的補碼 )
System.out.println(byte233);
// -23

java 補碼實踐