今天作LeetCode看到一道題,翻轉整型,其中一行代碼if ((newResult - tail) / 10 != result)
表示超出範圍就會有損失,有點不太明白,正好以前複習過原碼,反碼,補碼這些,研究了半天,寫個總結。接下來從兩個問題入門看計算機內部是如何計算的。html
咱們能夠用java代碼測試一下:java
System.out.println(Integer.MAX_VALUE + 1); System.out.println(Integer.MIN_VALUE); 打印: -2147483648 -2147483648 也就是-2^31
咱們知道帶符號整型的取值範圍是[-2^31 ~ 2^31-1],在計算機中是以補碼的形式存儲的,先來複習一下什麼是補碼,反碼和原碼:測試
正整數的原碼,反碼和補碼同樣,符號位固定爲0。 負整數的符號位爲1: 反碼 = 原碼各位取反(除第一位符號位) 補碼 = 反碼 + 1 以-1爲例: 原碼:10000000,00000000,00000000,00000001 反碼:11111111,11111111,11111111,11111110 補碼:11111111,11111111,11111111,11111111 計算機內部是使用補碼存儲而且計算的,那麼-1-1的過程就是 -1的補碼 11111111,11111111,11111111,11111111 - 1 獲得-2的補碼:11111111,11111111,11111111,11111110 那麼-2的反碼:11111111,11111111,11111111,11111101 那麼-2的原碼:10000000,00000000,00000000,00000010
有了這個基礎咱們來看一下爲何Integer.MAX_VALUE + 1 = Integer.MIN_VALUE
:code
Integer.MAX_VALUE的二進制是: 01111111,11111111,11111111,11111111 +1獲得 10000000,00000000,00000000,00000000 這是補碼,根據補碼能夠獲得反碼: 11111111,11111111,11111111,11111111 注意:可能發現10000000,00000000,00000000,00000000 - 1應該是 01111111,11111111,11111111,11111111啊,由於負整數符號位不變,所以符號位由0變爲1. 進而獲得原碼: 10000000,00000000,00000000,00000000 由於00000000,00000000,00000000,00000000已經表示爲0了,計算機規定10000000,00000000,00000000,00000000就表明負整數的最小值即Integer.MIN_VALUE。 所以Integer.MIN_VALUE的 補碼:10000000,00000000,00000000,00000000 反碼:11111111,11111111,11111111,11111111 原碼:10000000,00000000,00000000,00000000 接着看一下Integer.MIN_VALUE + 1 補碼:10000000,00000000,00000000,00000001 反碼:10000000,00000000,00000000,00000000 原碼:11111111,11111111,11111111,11111111
Integer.MAX_VALUE * 10在計算機內部就是10個Integer.MAX_VALUE相加(好像是...) Integer.MAX_VALUE的二進制爲: 01111111,11111111,11111111,11111111 首先看一下Integer.MAX_VALUE * 2就是 01111111,11111111,11111111,11111111 + 01111111,11111111,11111111,11111111 = 11111111,11111111,11111111,11111110(補碼) 11111111,11111111,11111111,11111101(反碼) 10000000,00000000,00000000,00000010(原碼) 因此Integer.MAX_VALUE * 2 = -2 能夠使用System.out.println(Integer.MAX_VALUE * 2); 驗證一下! 接下來能夠一步一步計算出Integer.MAX_VALUE * 10,就是10個Integer.MAX_VALUE相加 最後結果爲: 11111111,11111111,11111111,11110110(補碼) 11111111,11111111,11111111,11110101(反碼) 10000000,00000000,00000000,00001010(原碼) 即-10.
爲何計算機內部要用補碼進行計算,能夠看看這篇文章:htm