前言
在涉及与金融相关的计算中,有时候很容易忽略int, long 数相加时的溢出了最大边界或最小边界,如果if
分支判断恰好要求两数相加小于某一个值时,而你的两数相加刚好溢出变成负数,此时就会造成不正确的运行结果,导致事故发生。
MathUtils.addAndCheck
org.apache.commons.math.util 包下已经为我们封装了两数相加的安全检查,源码理解起来也比较简单,再也不用担心溢出而出事故了。
- 导入包
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math</artifactId>
<version>2.2</version>
</dependency>
- 使用示例
public static void main(String[] args) {
int num1 = Integer.MAX_VALUE + Integer.MAX_VALUE;
System.out.println(num1);
int num2 = MathUtils.addAndCheck(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
运行结果:
MathUtils.addAndCheck
重载了两个方法,如下:
public static int addAndCheck(int x, int y) {
long s = (long)x + (long)y;
if (s < Integer.MIN_VALUE || s > Integer.MAX_VALUE) {
throw MathRuntimeException.createArithmeticException(LocalizedFormats.OVERFLOW_IN_ADDITION, x, y);
}
return (int)s;
}
public static long addAndCheck(long a, long b) {
return addAndCheck(a, b, LocalizedFormats.OVERFLOW_IN_ADDITION);
}
private static long addAndCheck(long a, long b, Localizable pattern) {
long ret;
if (a > b) {
// use symmetry to reduce boundary cases
ret = addAndCheck(b, a, pattern);
} else {
// assert a <= b
if (a < 0) {
if (b < 0) {
// check for negative overflow
if (Long.MIN_VALUE - b <= a) {
ret = a + b;
} else {
throw MathRuntimeException.createArithmeticException(pattern, a, b);
}
} else {
// opposite sign addition is always safe
ret = a + b;
}
} else {
// assert a >= 0
// assert b >= 0
// check for positive overflow
if (a <= Long.MAX_VALUE - b) {
ret = a + b;
} else {
throw MathRuntimeException.createArithmeticException(pattern, a, b);
}
}
}
return ret;
}
分别是对int类型和long类型的加法检查,当发生正溢出或者负溢出时都会抛出异常。