基于源碼的個人理解 如有誤解請指正
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
如果有用麻煩點個喜歡,對我是莫大的鼓勵。