a減b小于0與a小于b什么區(qū)別?溢出感知代碼?

讀過JDK源碼的同學(xué),尤其是讀過Collection框架的同學(xué),肯定遇到過下面這種代碼:

BAT面試必問:a減b小于0與a小于b什么區(qū)別?溢出感知代碼?

第一次讀到這樣的代碼,你可能跟我一樣感到困惑,為什么不直接寫成 "newCapacity < minCapacity",而是更麻煩的"newCapacity – minCapacity < 0"呢?

BAT面試必問:a減b小于0與a小于b什么區(qū)別?溢出感知代碼?

不過,當(dāng)看到那個(gè)注釋"overflow-conscious code"之后,你或許明白了一點(diǎn)點(diǎn),這是為了解決數(shù)值溢出問題。

那么"newCapacity < minCapacity"中究竟有什么樣的溢出問題?"newCapacity – minCapacity < 0"是怎么解決"newCapacity < minCapacity"中的溢出問題的?究竟是newCapacity和minCapacity中的哪個(gè)變量溢出?還是兩個(gè)變量都溢出?對(duì)于這些問題,你都能給出清晰的回答嗎?如果不能,歡迎繼續(xù)閱讀!

本文以下面這段代碼為例,幫助大家徹底弄明白a<b與a-b<0有何區(qū)別的問題。在后面的分析中,我們假設(shè)入?yún)和b都大于0,沒有溢出;calc1和calc2是兩個(gè)計(jì)算函數(shù),會(huì)返回一個(gè)比原來更大的數(shù)值,而且可能溢出(例如乘以2、向左移位等)。

BAT面試必問:a減b小于0與a小于b什么區(qū)別?溢出感知代碼?

首先,上面代碼的入?yún)和b一開始都大于0。a經(jīng)過calc1()之后,一定變大而且可能溢出;b經(jīng)過calc2()也必然比原來的b大,也可能溢出。想通過"a-b<0"或"a<b"返回兩者中較小的一個(gè)。

顯然,a和b不溢出時(shí),a-b<0與a<b等價(jià),沒啥好分析的。是a溢出或b溢出導(dǎo)致了a-b<0與a<b之間的不同。所以我們的分析思路應(yīng)該是,討論分別在"a,b都不溢出"、"a溢出,b不溢出"、"a不溢出,b溢出"及"a,b都溢出"這4種情況下,"a<b"與"a-b<0"的結(jié)果如何,這些結(jié)果分別與預(yù)期結(jié)果是否相同,這樣就能把問題分析清楚了。所以,我們用分類討論的方法來分析問題,如下圖(ps. 分類討論方法是一種強(qiáng)大的分析手段,任何讓人感到復(fù)雜的、沒有頭緒的問題都可以用它解決)。

BAT面試必問:a減b小于0與a小于b什么區(qū)別?溢出感知代碼?

分解出4種情況之后,問題就變得簡(jiǎn)單明了多了,很容易得到a<b與a-b<0的實(shí)際結(jié)果,是true還是false。另外,期望結(jié)果應(yīng)該是數(shù)學(xué)上的,不考慮溢出問題。我們經(jīng)過分析,得到這4種情況下,a<b與a-b<0的實(shí)際結(jié)果與期望結(jié)果的對(duì)比,匯總?cè)缦拢?/p>

BAT面試必問:a減b小于0與a小于b什么區(qū)別?溢出感知代碼?

在上圖的分析中,我們沒有給出具體數(shù)值,只用了模糊的字眼"很大"、"很小"之類的,應(yīng)該不影響理解。如果你喜歡刨根問底,可以用這段程序分析一下,看看上面的總結(jié)對(duì)不對(duì)。

BAT面試必問:a減b小于0與a小于b什么區(qū)別?溢出感知代碼?

從上面分析可以看出,a-b<0這樣的寫法不是萬能的,并不能解決全部溢出問題,它在某些溢出情況下的依然錯(cuò)誤。而JDK之所以采用這種寫法,是因?yàn)閍和b的數(shù)值比較接近,而且都是大數(shù),在這個(gè)時(shí)候,a和b中有一個(gè)變量先溢出,另一個(gè)數(shù)往往很大了(快要溢出),用a-b<0的寫法剛好得到正確結(jié)果。JDK采用的這種a-b<0寫法,一般出現(xiàn)在各種空間分配方法中,例如ensureCapacity。而分配空間的時(shí)候,新分配的空間大小數(shù)值雖然比上一次的大,但是也比老的值差不了多少,巧妙的用上了上述綠色區(qū)域,實(shí)現(xiàn)了在數(shù)值溢出的情況下,依然正確的特性,非常神奇。

原文:https://www.toutiao.com/i6742359554706653708/?tt_from=mobile_qq&utm_campaign=client_share&timestamp=1597028450&app=news_article&utm_source=mobile_qq&utm_medium=toutiao_android&use_new_style=1&req_id=20200810110050010011049108167AE5BC&group_id=6742359554706653708

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容