摘要:正數的原碼,反碼和補碼相同。變量原碼反碼是符號位不變,其他位取反反碼補碼則是在反碼的基礎上加補碼所以在計算機中正確的表示應該是。原碼反碼補碼此刻開始轉換為類型,占個字節,符號位,用填充高位三個字節。
我們都知道計算機存儲的是二進制,長度是8個比特。
byte b = 10; int i = -10; long l = 10L;
那么以上幾個變量如何用二進制表示呢?
很多人第一印象肯定是 b變量占用一個字節,也就是8位,所以 b用二進制表示就是 1010,高位補零,所以是 00001010。那么i是int,占用4個字節,也就是32位,但因為是負數,所以最高位是100000000 00000000 00000000 00001010。同理 l變量則是 00000000 00000000 00000000 00000000 000000000 00000000 00000000 00001010。
上面的推理過程中存在一處錯誤,就是在java中存儲的是補碼,而不是原碼。正數的原碼,反碼和補碼相同。負數則不是一樣。以上面 int i = -10 作為例子。
變量 i 原碼 1000 1010 # 反碼是符號位不變,其他位取反 反碼 1111 0101 #補碼則是在反碼的基礎上加1 補碼 1111 0110
所以-10 在計算機中正確的表示應該是 1111 0110。
上面我們已經學習原碼,反碼和補碼相關的概念,至于為什么要用補碼,感興趣的可以自己去查。
我們也知道在網絡傳輸中,存儲的就是二進制相關的byte數組。那么現在我們需要往消息中寫入int或者long相關的信息,如何轉換為byte數組中的相關項?第一個想到的辦法就是強制轉換。
int x = 135; System.out.println((byte)x); /** 輸出-121 **/ x = -135; System.out.println((byte)x); /** 輸出-121 **/
可見輸出的答案并不如你所愿。想知道為什么這樣嗎?感興趣的可以自己去推導。
額,還是幫你們推導一遍吧。我們以 -135為例。
首先我們知道 int 占用4個字節,而byte占用1個字節,同時你也看到 -135已經超出了一個字節所能表示的范圍[-128, 127]。如果強制轉換后還能顯示出正確結果,那才恐怖啊。
-135 原碼 10000000 00000000 00000000 10000111 反碼 11111111 11111111 11111111 01111000 補碼 11111111 11111111 11111111 01111001
我們知道java中存儲的是補碼,可是因為byte只占一個字節,所以轉換的時候只取到最低位那個字節也就是 01111001作為轉換后補碼存在。因為正數的原碼和補碼相同,也即是這個字節的原碼是01111001,原值是 121。
剛才我們討論的是int強制轉換成byte類型可能存在的問題。那么如果我需要把byte類型的強制轉換成int類型的會出現什么樣的問題。
byte num = 120; System.out.println((int)num); num = -120; System.out.println((int)num);
大家看到這兩行示例代碼時。盡量自己嘗試推導出結果來,不要看我下面的推導過程。
我們以-120作為例子,嘗試推導下(看到沒有,我喜歡負數)。
-120 原碼 11111000 反碼 10000111 補碼 10001000 ##此刻開始轉換為int類型,占4個字節,符號位1,用1填充高位三個字節。如果符號位是0,高位會用0填充。 補碼 11111111 11111111 11111111 10001000 /** 存儲在內存中的int整形補碼 **/ 反碼 11111111 11111111 11111111 10000111 原碼 10000000 00000000 00000000 01111000 原值 -120
所以 當 byte num = -120 時, (int)num = -120
我相信很多人都沒有自己推導,直接看我的推導的。那么再給你個機會,嘗試推導下當byte num = 120的時候推導過程。
通過byte強制轉換成int 好像一切都很順利,也沒有int強制轉換成byte相關的問題。
當真的是那樣嗎?下一篇我們繼續探討這個話題。
原文鏈接 http://segmentfault.com/a/1190000003758605/
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/64539.html
摘要:雖然發生了符號位擴展,但是沒有任何問題。這就是計算機中原碼和補碼的奧秘之處。不過等你看懂了就會發現位運算的巧妙之處。這個函數的作用呢其實就是計算整形變量高位連續為零的個數。比如時二進制補碼就是原碼也就是,那么得到的結果應該是。 上一篇文章我們討論到byte強制轉換成int。然后拋出了一個問題,就是byte直接強制轉換成int一定會沒問題嗎?還是因為上面我們推導的那個例子只是個特例。好吧...
摘要:所以就想把一大串縮短點,將二進制中的三位用一位表示。以可以大寫也可以小寫開頭版本可以表示二進制了八進制的數據表現形式由組成。結果把系數基數的權次冪相加即可。因為語言采用的是碼來編碼的。 1_(常量的概述和使用)* A:什么是常量(constant) 在程序執行的過程中其值不可以發生改變 B:Java中常量的分類 字面值常量 自定義常量(面向對象部分講) C:字面值常量的...
摘要:局部變量聲明在函數內部的變量。在作用域范圍內不能出現命名沖突。 java編程規范: 1.良好的標識符的命名 保留字不能作為標識符命名: class、public、static..., goto,const 區分大小寫:helloWorld、HelloWorld 2.良好的注釋習慣 3.良好的縮進:沒遇到一個代碼塊縮進一次(一個tab鍵) 變量:代...
摘要:系列密碼學二傳送門密碼學一基礎密碼學算法分類消息編碼消息摘要類,類,對稱密碼非對稱密碼數字簽名五元組明文原始信息。非對稱密碼包提供給,,等非對稱加密算法。對稱加密算法在分布式網絡系統上使用較為困難,主要是因為密鑰管理困難,使用成本較高。 前言 最近一場面試,面試官問了我 對稱加密與非對稱加密的問題,雖然曾經看過一些內容,但是沒有系統的整理,所以當被問的時候,腦子里一片空白,沒有回答上...
閱讀 2309·2021-08-26 14:14
閱讀 2678·2019-08-29 13:07
閱讀 2084·2019-08-26 11:44
閱讀 676·2019-08-26 10:11
閱讀 2410·2019-08-23 15:43
閱讀 3080·2019-08-23 14:17
閱讀 385·2019-08-23 12:36
閱讀 2082·2019-08-22 15:20