Java整型計算

整型計算

今天作LeetCode看到一道題,翻轉整型,其中一行代碼if ((newResult - tail) / 10 != result)表示超出範圍就會有損失,有點不太明白,正好以前複習過原碼,反碼,補碼這些,研究了半天,寫個總結。接下來從兩個問題入門看計算機內部是如何計算的。html

1. 爲何Integer.MAX_VALUE + 1 = Integer.MIN_VALUE

咱們能夠用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

2. 爲何Integer.MAX_VALUE * 10 = -10

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

https://www.cnblogs.com/rayth...blog

相關文章
相關標籤/搜索