關於原碼反碼和補碼以及byte&0xff


1. 問題由來

本筆記是由byte&0xff引申出來的。在看某一段代碼的時候發現有這么一個邏輯:

 

該方法的功能是把四個元素的byte數組轉換成ip4地址,從debug的中間過程可以看出來src的第二個元素為負數-100,但它確實是表示ip地址的第二個字節,且src[1] & 0xff之后又變為了正數156,這其中的現象如何解釋?要想知道這里面的原因,首先需要知道原碼、反碼和補碼的概念。

2. 原碼、反碼和補碼

數字是可以二進制來表示的,比如8的二進制表示為00001000,-8的二進制為10001000,其中最高位為符號位。對於正數來說,其二進制原碼,反碼,補碼均相同。而對於負數來說,反碼等於符號位位不變,其余各位取反;補碼等於其反碼加1。

比如問題中的156,其二進制表示為10011100,其反碼和補碼也是10011100。而-100的二進制表示為11100100,其反碼為10011011,補碼為1011100。這時候會發現156的原碼和-100的補碼是一致的。

3. byte & 0xff的細節

我們知道byte是java的一種基本類型,其大小為一個字節,表示的整數范圍是-128~127。而當其最高為不解釋為符號位時,其最大可以表示的數為255。因此例子中字節數組的第二個元素debug時被解釋為-100的原因是,156的二進制表示正好可以解釋為帶符號byte的-100,且我們可以發現byte中存儲的內容其實是補碼。

ok,第一個問題清楚了,-100的補碼與無符號的156的二進制表示一致,且java中的byte存儲的是補碼。那么,為什么src[1] & 0xff之后就變回了正數呢?講道理,0xff可以表示為11111111,我們知道和1與運算之后還是其本身,乍一看,這個運算是沒有意義的。

0xff究竟是怎么一回事呢。可以考慮一下下面這段代碼中c的值會是什么:

int a = 255;
int b = 0xff;
boolean c = a == b;

c的值為true。其實0xff與255沒有本質的區別,一個是十進制一個是十六進制,都是用來表示一個int型正數。回道上面的問題,src[1] & 0xff也就是src[1]與一個整數相與,那么src[1]首先就要先轉換成一個四字節的整數:

11111111 11111111 11111111 10011100,而0xff為一個整數,其四字節表示為00000000 00000000 00000000 1111111,兩者相與的結果為00000000 00000000 00000000 10011100,也即是解釋為整數156,這樣也就達到了想要獲取byte中實際裝入的無符號156的目的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM