楼子湾

导航

统计
 

前端突然报了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     }

 

posted on 2020-03-09 19:14  楼子湾  阅读(...)  评论(...编辑  收藏