Java千問:Java語言中最大的整數再加1等於多少?

已知Java語言中int類型所能表示的最大整數爲2147483647,請問如下代碼執行結果是什麼?
Java千問:Java語言中最大的整數再加1等於多少?
一部分人都會認爲這段程序壓根就沒法經過編譯,也有人認爲,這段程序可以經過編譯,但在運行時會拋出異常,但更多的人面對這道題目根本就無從下手。那麼正確答案是什麼呢?首先告訴你們,這段程序可以順利經過編譯,而且在運行時也不會出現異常,運行的結果是在控制檯上輸出了數字-2147483648!而-2147483648正好是Java語言中int類型所能表示的最小整數。
這個運行結果可能會讓不少人感到大跌眼鏡,運行結果爲何會是這樣的呢?想弄明白其中的原理,就必須先弄清楚Java語言中數字的表示和存儲方式。
你們都知道:任何一個數字,存儲到計算機當中,都是以二進制的形式進行存儲的。在Java語言中,使用補碼的形式來表示數字。那麼補碼是個什麼東西呢?補碼就是計算機用二進制的形式表示數字的一種規則。它的算法很簡單:用最左邊的一個二進制位表示數字的正負,0表示正數,1表示負數,咱們把表示符號的這個二進制位叫作「符號位」,而剩餘的二進制位表示數字自己。至於怎樣用其他的二進制位表示數字,正數和負數略有區別。咱們首先來講正數的狀況。對於正數而言,直接用剩餘二進制位表示這個數字就能夠了。而對於負數而言,算法稍微複雜一點,分爲兩步:
1、用補碼錶示出這個數的絕對值,以後把每一個位上的數字(連同符號位上的數字在內)按位取反,所謂按位取反就是若是這個位上原來是0,那麼就變成1,若是原來這個位上原來是1,那麼就變成0。
2、就是把這個取反之後的數字加上1,就獲得了負數的補碼錶示結果。
沒看懂?不要緊!我們用例子說事。首先必須知道,Java語言中int類型的數據佔4個字節,那麼4個字節所能表示的最大整數是多少呢?按照補碼的表示規則,這個最大的整數存儲到計算機當中應該是「1個0跟31個1」:
Java千問:Java語言中最大的整數再加1等於多少?
若是咱們強行給這個數再加1,按照二進制的進位規則,它會變成下面的樣子:
Java千問:Java語言中最大的整數再加1等於多少?
這個數是多少?會是0嗎?咱們來分析一下:首先最左邊的符號位從0變成了1,因此能夠確定,這個數是個負數。那麼一個正數作了加1的操做,它應該變成一個更大的正數,如今怎麼變成負數了呢?咱們必須清楚,原來這個數的符號位是0,是由於加法運算產生了「進位」,才使得符號位變成了1,可是,計算機無論那麼多,它只要看到最左邊的符號位是1,就認定這是一個負數。那麼,這個負數的值是多少?咱們能夠按照補碼錶示負數的規則,以逆運算的方式求出它的絕對值,就知道這個負數的值了。
前面講過:用補碼錶示負數的算法分兩步進行,其中第二步,是在二進制數字上加1。那麼反過來,這個過程的逆運算也要分兩步進行。其中第一步就應該是在原負數補碼的數字上減1,減1以後,剛纔的數字就會變成下面的樣子
Java千問:Java語言中最大的整數再加1等於多少?
補碼求負數的第一步是對二進制數字按位取反,因此逆運算的第二步也是對各個位上的數字(連同符號位上的數字在內)按位取反,使得各個位數字恢復到原來的值。通過按位取反以後,剛纔那個二進制數字又會變成下面的樣子
Java千問:Java語言中最大的整數再加1等於多少?
細心的讀者可能已經發現,折騰了半天,又回到了逆運算以前的樣子!你們注意:表面上,這個二進制數跟逆運算以前是一個樣,可是它的意義已經徹底不一樣了。在進行逆運算以前,這個二進制數是一個補碼形式表示的負數,而通過逆運算以後,這個二進制數變成了一個絕對值,既然是絕對值,它確定不會是負數。所以,這個二進制數最前面的1並不表示負數,而是數字的一部分。那麼這個絕對值是多少呢?轉換成十進制就是2147483648。因此,咱們圖3中看到的那個「1開頭後面跟着31個0」所表示的負數,就是-2147483648!
到此爲止,我想你們已經明白爲何程序的運行結果是-2147483648了吧?可能有一部分讀者會問:補碼當中,「1開頭後面跟着31個0」這個數字爲何不能解釋爲:符號位上的1表示負數,後面的31位數字表示0,這樣造成的數字是-0,也就是0呢?其實,補碼的運算規則中特地強調了這一點。規則強調:補碼當中,對於0只有惟一一種表示形式,那就是32個0,其中最前面的0表示符號,後面的0表示數字。一旦遇到符號位是1,後面全是0的狀況,必須按負數對待!既然要求咱們按負數對待,那就必須經過逆運算來計算這個負數的絕對值。而咱們計算獲得的這個負數的絕對值就是2147483648。-2147483648是int類型的所能表示的最小值。所以,int類型數據的最大值再加1,一會兒就變成了int類型的最小值,咱們能夠戲稱爲「物極必反現象」。
那麼,Java語言當中,其餘三種類型的整數是否也有「物極必反現象」呢?對於long類型的變量來說,也存在這種現象,而對於byte和short類型,咱們使用其最大值和1進行加法運算,沒法再賦值給byte和short型的變量,由於這種操做在編譯時就會報錯。關於byte和short變量沒法完成這種賦值操做的緣由,你們能夠看《Java千問:Java語言中爲byte和short類型變量賦值爲啥會報錯?》進行詳細瞭解。
另外,經過這個例子,你們也應該明白爲何Java語言中,整數類型的表示範圍是不對稱的。好比, byte類型的數據最大值是是127,而最小並非-127,而是-128。其緣由就是補碼規則中,把0看成了正數看待,這樣的話正數這邊有個0,而負數那邊沒有,從而表示範圍不對稱。html

若是想系統學習Java編程,能夠點擊這裏觀看個人視頻課程。有問題也能夠加入個人QQ羣291839907一塊兒討論。算法

相關文章
相關標籤/搜索