为什么使用Guava Math
-
Guava Math针对各种不常见的溢出情况都有充分的测试;对溢出语义,Guava文档也有相应的说明;如果运算的溢出检查不能通过,将导致快速失败。
-
Guava Math的性能经过了精心的设计和调优;虽然性能不可避免地依据具体硬件细节而有所差异,但Guava Math的速度通常可以与Apache Commons的MathUtils相比,在某些场景下甚至还有显著提升。
-
Guava Math在设计上考虑了可读性和正确的编程习惯;IntMath.log2(x, CEILING) 所表达的含义,即使在快速阅读时也是清晰明确的。而32-Integer.numberOfLeadingZeros(x – 1)对于阅读者来说则不够清晰。
一 整数运算
Guava Math主要处理三种整数类型:int、long和BigInteger。这三种类型的运算工具类分别叫做IntMath、LongMath和BigIntegerMath。
1.1 有溢出检查的运算
有溢出检查的运算,如果计算结果有溢出的情况下(上溢,下溢),就会抛出ArithmeticException异常。
运算(有溢出检查) | IntMath里面方法 | LongMath里面方法 |
---|---|---|
加法 | checkedAdd(int a, int b) | checkedAdd(int a, int b) |
减法 | checkedSubtract(int a, int b) | checkedSubtract(int a, int b) |
乘法 | checkedMultiply(int a, int b) | checkedMultiply(int a, int b) |
幂 | checkedPow(int b, int k) | checkedPow(int b, int k) |
1.2 上溢,下溢返回最大值最小值
如果对应的运算如果发生溢出,上溢则返回对应类型的最大值(Integer.MAX_VALUE、Long.MAX_VALUE )、下溢则返回对应类型的最小值(Integer.MIN_VALUE、Long.MIN_VALUE)。
运算 | IntMath里面方法 | LongMath里面方法 |
---|---|---|
加法 | saturatedAdd(int a, int b) | saturatedAdd(int a, int b) |
减法 | saturatedSubtract(int a, int b) | saturatedSubtract(int a, int b) |
乘法 | saturatedMultiply(int a, int b) | saturatedMultiply(int a, int b) |
幂 | saturatedPow(int b, int k) | saturatedPow(int b, int k) |
二 实数运算
IntMath、LongMath和BigIntegerMath提供了很多实数运算的方法,并把最终运算结果舍入成整数。这些方法需要指定一个java.math.RoundingMode枚举值来作为舍入的模式。RoundingMode的取值如下:
RoundingMode枚举值 | 解释 |
---|---|
RoundingMode.DOW | 向零方向舍入(去尾法) |
RoundingMode.UP | 远离零方向舍入 |
RoundingMode.FLOO | 向负无限大方向舍入 |
RoundingMode.CEILING | 向正无限大方向舍入 |
RoundingMode.UNNECESSARY | 不需要舍入,如果用此模式进行舍入,应直接抛出ArithmeticException |
RoundingMode.HALF_UP | 向最近的整数舍入,其中x.5远离零方向舍入 |
RoundingMode.HALF_DOWN | 向最近的整数舍入,其中x.5向零方向舍入 |
RoundingMode.HALF_EVEN | 向最近的整数舍入,其中x.5向相邻的偶数舍入 |
实数运算方法
运算 | IntMath里面方法 | LongMath里面方法 | BigIntegerMath里面方法 |
---|---|---|---|
除法 | divide(int, int, RoundingMode) | divide(long, long, RoundingMode) | divide(BigInteger, BigInteger, RoundingMode) |
2为底的对数 | log2(int, RoundingMode) | log2(long, RoundingMode) | log2(BigInteger, RoundingMode) |
10为底的对数 | log10(int, RoundingMode) | log10(long, RoundingMode) | log10(BigInteger, RoundingMode) |
平方根 | sqrt(int, RoundingMode) | sqrt(long, RoundingMode) | sqrt(BigInteger, RoundingMode) |
实数运算部分Guava还另外提供了一些有用的运算函数
运算 | IntMath里面方法 | LongMath里面方法 | BigIntegerMath里面方法 |
---|---|---|---|
最大公约数 | gcd(int, int) | gcd(long, long) | gcd(BigInteger) |
取模 | mod(int, int) | mod(long, long) | mod(BigInteger) |
取幂 | pow(int, int) | pow(long, int) | pow(int) |
是否2的幂 | isPowerOfTwo(int) | isPowerOfTwo(long) | isPowerOfTwo(BigInteger) |
阶乘* | factorial(int) | factorial(int) | factorial(int) |
二项式系数* | binomial(int, int) | binomial(int, int) | binomial(int, int) |
*阶乘和二项式系数的运算结果如果溢出,则返回MAX_VALUE
三 浮点数运算
JDK已经比较彻底地涵盖了浮点数运算,但Guava在DoubleMath类中也提供了一些有用的方法。
运算 | DoubleMath方法 |
---|---|
判断该浮点数是不是一个整数 | isMathematicalInteger(double) |
舍入为int;对无限小数、溢出抛出异常 | roundToInt(double, RoundingMode) |
舍入为long;对无限小数、溢出抛出异常 | roundToLong(double, RoundingMode) |
舍入为BigInteger;对无限小数抛出异常 | roundToBigInteger(double, RoundingMode) |
2的浮点对数,并且舍入为int,比JDK的Math.log(double) 更快 | log2(double, RoundingMode) |
关于Guava属性运算的一些帮助类就这些。使用非常简单。我们就不举例了。
网友评论