天天看點

整數溢出展現的哲學道理

 一、背景

今天一個小夥伴發了一個demo,問結果是啥,為什麼?

public class WhileTest {
    public static void main(String[] args) {
        int i  = 0;
        while (true){
            i++;
            if(i == 10){
                System.out.println(i);
            }
        }
    }
}      
整數溢出展現的哲學道理

有些回答10,有些回答居然是9.....

小夥伴們運作就會發現,列印了好多次10。

可能很多小夥伴覺得so easy,溢出了呗,負數了呗。

請問哪個負數?最大值+1是幾?

能不能清晰地從二進制角度去講解?

面試官說:if 能  then 能否講講展現出啥哲理??

are you kidding me ?咋還扯到哲學了!?

這個面試官惹不起,咱不面了,還是主動回家等消息吧......

二、分析

首先這是單線程(單線程都是順序執行的),if條件是等于10為真,怎麼可能列印出來的是9????

另外的話我們看,初始化是0,然後while循環是恒真的,那麼i++會一直執行,當加到10的時候  下面肯定會列印出來的。

那麼然後呢??然後一直增加對吧?

那麼如果一直增加到整數最大值怎麼辦??會發生什麼???

我們先看下整數最大值如果再+1會怎樣?

int i = Integer.MAX_VALUE;
 System.out.println(i+1);
System.out.println(Integer.MIN_VALUE);      
整數溢出展現的哲學道理

發現結果是:-2147483648,是負數!!而且是整數的最小值!

是以再一直加1是不是又到了0 然後到10,然後又列印一次對吧,然後繼續循環.....

那麼為什麼會醬紫??

int 類型在 Java 中是“有符号”的,所謂“有符号”就是有正負。

大家知道計算機中用二進制表示所有的資訊,java中整數是4個位元組(一個位元組8位)即32位,其中首位是符号位,如果是1表示負數,0則表示整數。

但是如果正數過大了,例如 2^31,計算機不得不把首位變成 1,并且很快就忘了這是溢出情況,把它按照正常的方式輸出了,于是就成了負的。

其實也不能怪它,它沒有辦法自動處理超過溢出的情況,因為 32 位是固定的,它不能因為溢出而臨時擴充到 33 位之類的。

這和鐘表很相似,

整數溢出展現的哲學道理

十二小時表示法的時鐘,轉到了中午12點,然後會怎樣???

盤面就那麼大總不能給你變出個13吧?雖然我們知道是下午1點,但是其盤面的效果和淩晨1點沒差別。

2^31 - 1 = 0111 1111 1111 1111 1111 1111 1111 1111 = 2147483647

2^31      = 2^31 - 1 + 1 = 1000 0000 0000 0000 0000 0000 0000 0000 = -2147483648

溢出變成 0 的話道理也一樣。你想如果一個數大到最後 32 位都是 0 了,那計算機隻能把它認作 0。

這種情況有很多,例如 2^32 就是一共 33 位,首位 1,後面 32 位都是 0。

我們從二進制的角度可以清晰的認識到,2^31 - 1 = 0111 1111 1111 1111 1111 1111 1111 1111 = 2147483647  加一後(二進制逢二進一)确實是整數能表示的最小值     2^31      = 2^31 - 1 + 1 = 1000 0000 0000 0000 0000 0000 0000 0000 = -2147483648。

另外為啥整數的最大值是2的31次方-1,而不是32次方??

因為首位是符号位,是以資料位隻有31位。31位全為1才是最大值

那麼值為 2^30+2^29+...+2^0 = 2^31-1次。

為啥最小值是2^31?

最小值肯定為負數,則首位為1,那麼剩下31位最小的話必定都為0。是以值為1*2^31+0+...+0=2^31。

三、教訓

1996年6月4日,阿麗亞娜5型運載火箭(Ariane 5)在法國庫魯的歐洲運載火箭發射場發射,37秒後火箭解體并爆炸。火箭的開發費用大約70億美元,火箭本體及運載的裝置價值約5億美元。兩周後的調查報告指出,爆炸原因由于火箭某段控制程式直接移植自阿麗亞娜4型火箭,其中一個需要接收64位資料的變量為了節省存儲空間而使用了16位位元組,進而在控制過程中産生了整數溢出,導緻導航系統對火箭控制失效,程式進入異常處理子產品,引爆自毀。
整數溢出展現的哲學道理

這都是不細心和基礎不紮實惹的禍!

知道為什麼面試中愛問各種資料類型的範圍了吧?

開發中要選取最合适的資料類型,考慮極端情況,比如整數溢出的問題,訂單Id等增長較快的整型要設定為長整型。

四、延伸

4.1 “物極必反”、“否極泰來”

另外讓我想到了兩個詞語“物極必反”、“否極泰來”(雖然不完全一緻,思想是一緻的)

物極必反

【解釋】:極:頂點;反:向反面轉化。事物發展到極點,會向相反方向轉化。

【出處】:《呂氏春秋·博志》:“全則必缺,極則必反。”《鹖冠子·環流》:“物極則反,命曰環流。”

否極泰來

【解釋】否、泰:《周易》中的兩個卦名。否:卦不順利;泰:卦順利;極:盡頭。逆境達到極點,就會向順境轉化。指壞運到了頭好運就來了。

【出處】《周易·否》:“否之匪人,不利君子貞,大往小來。”《周易·泰》:“泰,小往大來,吉亨。”《吳越春秋·勾踐入臣外傳》:“時過于期,否終則泰。

我們整數不斷增加到最大值,然後“物極必反”就轉化為了負數。我們整數的最小值即“否極”然後不斷增加即“泰來”。

可見中國古人的智慧。

4.2 沖突的對立統一

這點和馬克思主義哲學上的“沖突對立統一”是一緻的,沖突的同一性的第三條就講到:

沖突雙方在一定條件下互相轉化。你能變成我,我能變成你。

4.2 數學函數

這點和數學的一些函數很相似,正弦函數為例(雖然不完全一緻,思想是一緻的),它是有範圍的-1到1,到最高點則會降低。

整數溢出展現的哲學道理

三、思考

我們遇到問題要從根本上去了解它,而不是僅僅觀察這個現象,知道怎麼解決這個問題。

另外我們要嘗試把各個學科的思想結合在一起幫助自己去了解知識點。

創作不易,如果覺得本文對你有幫助,歡迎點贊,歡迎關注我,如果有補充歡迎評論交流,我将努力創作更多更好的文章。

另外歡迎加入我的知識星球,知識星球ID:15165241 一起交流學習。

https://t.zsxq.com/Z3bAiea  申請時标注來自CSDN。