Math.addExact如何解決加法溢出問題

基于源碼的個人理解 如有誤解請指正

Java中直接用運算符進行加法操作,會產(chǎn)生溢出:

int a = Integer.MAX_VALUE;
int b = 1;
int c = a+b;
System.out.println(c-Integer.MIN_VALUE);
//output:0

? 說明a+b產(chǎn)生了溢出,且值等于絕對值最大的負數(shù),負2的31次方。

? 為了解決這個問題,Math類提供了一個不會溢出的加法:

public static int addExact(int x, int y) {
        int r = x + y;
        // HD 2-12 Overflow iff both arguments have the opposite sign of the result
        if (((x ^ r) & (y ^ r)) < 0) {
            throw new ArithmeticException("integer overflow");
        }
        return r;
    }

? 原理其實很簡單。只有兩個正數(shù)或者兩個負數(shù)相加的時候才會溢出,一正一負是不會溢出的。并且,溢出后得到的結(jié)果一定是與原值的符號相反的。

? 借用這個原理,(x ^ r) & (y ^ r)將用運算符算出來的r與x和y分別異或。異或的規(guī)則是同0異1。我們只看符號位,如果符號位不同,那么兩個括號得到的都是1。而與運算又是只有1 & 1才是1,有一個為0都是0。因此,一旦溢出,無論是正溢出負溢出,(x ^ r) & (y ^ r)計算出的結(jié)果都應(yīng)該小于0

如果有用麻煩點個喜歡,對我是莫大的鼓勵。

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

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