1. 程式人生 > 其它 >Java中byte做&0xff運算的原因及解析

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的目的。


Shopee(蝦皮)內推點選此處,崗位多多地,薪資高高地

南來地,北往的,上班的,下崗的,走過路過不要錯過!

======================個性簽名=====================

之前認為Apple 的iOS 設計的要比 Android 穩定,我錯了嗎?

下載的許多客戶端程式/遊戲程式,經常會Crash,是程式寫的不好(記憶體洩漏?剛啟動也會嗎?)還是iOS本身的不穩定!!!

如果在Android手機中可以簡單聯接到ddms,就可以檢視系統log,很容易看到程式為什麼出錯,在iPhone中如何得知呢?試試Organizer吧,分析一下Device logs,也許有用.


對於部落格園裡的網友,不敢稱為叫"程式設計師"的人,你們攻擊性太強,看來你們是不會想到我的用意的.園子裡有不少人都非常喜歡Jeffrey,是因為它的第一版 框架設計 CLR via C#.
可是從第一版到現在的第三版,沒有看到真正底層的東西,內容僅僅是比MSDN文件更豐富一些,可能是我的要求太高了吧.
也就是因為它很多時候會接觸到微軟開發人員,會經常聊聊某些問題而已,而它又將這些問題反應到書中.也許它就像一個小記者.
它的年齡大我們不多,我的孩子與它小兒子一般大,如果我能向它那樣出入微軟與它們開發人員長時間交流,不僅僅會牛成它這樣.....
可是微軟的開發人員不會扔太多時間在它這兒的.所以它會整天追著這個,趕它那個..屁顛個不停吧...
而它的另一版被稱為好書的 Windows核心程式設計,更是沒有什麼深度可言,僅僅是將windows提供的api,以及核心功能再重申了一遍.
這些書對晉及程式設計知識是有些貢獻的,再說一遍我不是在匾低誰,說說想法而已.