前端突然報了integer overflow錯誤,int類型溢出也就是數字超過了int類型,一看很懵逼,查看后台日期發現是在Math.toIntExact()方法報錯
那么我們看下方法內部代碼:
1 /** 2 * Returns the value of the {@code long} argument; 3 * throwing an exception if the value overflows an {@code int}. 4 * 5 * @param value the long value 6 * @return the argument as an int 7 * @throws ArithmeticException if the {@code argument} overflows an int 8 * @since 1.8 9 */ 10 public static int toIntExact(long value) { 11 if ((int)value != value) { 12 throw new ArithmeticException("integer overflow"); 13 } 14 return (int)value; 15 }
從代碼中看出,它對參數value值進行了驗證,如果強轉為int仍然與原值相等說明沒有超過int的值范圍,否則拋出異常:integer overflow
我們在看看Math的其他方法,既然我們需要加減乘除,Math類肯定有現成的也會支持long類型的
這里只截出一部分,我們要用到的,這些都是1.8才有的方法
long類型的加減乘除運算:
加法:支持 int 和long的參數
1 */ 2 public static int addExact(int x, int y) { 3 int r = x + y; 4 // HD 2-12 Overflow iff both arguments have the opposite sign of the result 5 if (((x ^ r) & (y ^ r)) < 0) { 6 throw new ArithmeticException("integer overflow"); 7 } 8 return r; 9 } 10 11 /** 12 * Returns the sum of its arguments, 13 * throwing an exception if the result overflows a {@code long}. 14 * 15 * @param x the first value 16 * @param y the second value 17 * @return the result 18 * @throws ArithmeticException if the result overflows a long 19 * @since 1.8 20 */ 21 public static long addExact(long x, long y) { 22 long r = x + y; 23 // HD 2-12 Overflow iff both arguments have the opposite sign of the result 24 if (((x ^ r) & (y ^ r)) < 0) { 25 throw new ArithmeticException("long overflow"); 26 }
減法運算:
1 public static int subtractExact(int x, int y) { 2 int r = x - y; 3 // HD 2-12 Overflow iff the arguments have different signs and 4 // the sign of the result is different than the sign of x 5 if (((x ^ y) & (x ^ r)) < 0) { 6 throw new ArithmeticException("integer overflow"); 7 } 8 return r; 9 } 10 11 /** 12 * Returns the difference of the arguments, 13 * throwing an exception if the result overflows a {@code long}. 14 * 15 * @param x the first value 16 * @param y the second value to subtract from the first 17 * @return the result 18 * @throws ArithmeticException if the result overflows a long 19 * @since 1.8 20 */ 21 public static long subtractExact(long x, long y) { 22 long r = x - y; 23 // HD 2-12 Overflow iff the arguments have different signs and 24 // the sign of the result is different than the sign of x 25 if (((x ^ y) & (x ^ r)) < 0) { 26 throw new ArithmeticException("long overflow"); 27 }
乘法:
1 public static int multiplyExact(int x, int y) { 2 long r = (long)x * (long)y; 3 if ((int)r != r) { 4 throw new ArithmeticException("integer overflow"); 5 } 6 return (int)r; 7 } 8 9 /** 10 * Returns the product of the arguments, 11 * throwing an exception if the result overflows a {@code long}. 12 * 13 * @param x the first value 14 * @param y the second value 15 * @return the result 16 * @throws ArithmeticException if the result overflows a long 17 * @since 1.8 18 */ 19 public static long multiplyExact(long x, long y) { 20 long r = x * y; 21 long ax = Math.abs(x); 22 long ay = Math.abs(y); 23 if (((ax | ay) >>> 31 != 0)) { 24 // Some bits greater than 2^31 that might cause overflow 25 // Check the result using the divide operator 26 // and check for the special case of Long.MIN_VALUE * -1 27 if (((y != 0) && (r / y != x)) || 28 (x == Long.MIN_VALUE && y == -1)) { 29 throw new ArithmeticException("long overflow"); 30 } 31 } 32 return r; 33 }
除法:除法時鄉下取整的
1 public static int floorDiv(int x, int y) { 2 int r = x / y; 3 // if the signs are different and modulo not zero, round down 4 if ((x ^ y) < 0 && (r * y != x)) { 5 r--; 6 } 7 return r; 8 } 9 10 public static long floorDiv(long x, long y) { 11 long r = x / y; 12 // if the signs are different and modulo not zero, round down 13 if ((x ^ y) < 0 && (r * y != x)) { 14 r--; 15 } 16 return r; 17 }