Java中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的目的。
南來地,北往的,上班的,下崗的,走過路過不要錯過!
======================個性簽名=====================
之前認為Apple 的iOS 設計的要比 Android 穩定,我錯了嗎?
下載的許多客戶端程式/遊戲程式,經常會Crash,是程式寫的不好(記憶體洩漏?剛啟動也會嗎?)還是iOS本身的不穩定!!!
如果在Android手機中可以簡單聯接到ddms,就可以檢視系統log,很容易看到程式為什麼出錯,在iPhone中如何得知呢?試試Organizer吧,分析一下Device logs,也許有用.