Google Guava 数学运算 谁践踏了优雅 2021-12-12 08:33 343阅读 0赞 为什么使用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异常。 <table> <thead> <tr> <th>运算(有溢出检查)</th> <th>IntMath里面方法</th> <th>LongMath里面方法</th> </tr> </thead> <tbody> <tr> <td>加法</td> <td>checkedAdd(int a, int b)</td> <td>checkedAdd(int a, int b)</td> </tr> <tr> <td>减法</td> <td>checkedSubtract(int a, int b)</td> <td>checkedSubtract(int a, int b)</td> </tr> <tr> <td>乘法</td> <td>checkedMultiply(int a, int b)</td> <td>checkedMultiply(int a, int b)</td> </tr> <tr> <td>幂</td> <td>checkedPow(int b, int k)</td> <td>checkedPow(int b, int k)</td> </tr> </tbody> </table> ## 1.2 上溢,下溢返回最大值最小值 ## 如果对应的运算如果发生溢出,上溢则返回对应类型的最大值(Integer.MAX\_VALUE、Long.MAX\_VALUE )、下溢则返回对应类型的最小值(Integer.MIN\_VALUE、Long.MIN\_VALUE)。 <table> <thead> <tr> <th>运算</th> <th>IntMath里面方法</th> <th>LongMath里面方法</th> </tr> </thead> <tbody> <tr> <td>加法</td> <td>saturatedAdd(int a, int b)</td> <td>saturatedAdd(int a, int b)</td> </tr> <tr> <td>减法</td> <td>saturatedSubtract(int a, int b)</td> <td>saturatedSubtract(int a, int b)</td> </tr> <tr> <td>乘法</td> <td>saturatedMultiply(int a, int b)</td> <td>saturatedMultiply(int a, int b)</td> </tr> <tr> <td>幂</td> <td>saturatedPow(int b, int k)</td> <td>saturatedPow(int b, int k)</td> </tr> </tbody> </table> # 二 实数运算 # IntMath、LongMath和BigIntegerMath提供了很多实数运算的方法,并把最终运算结果舍入成整数。这些方法需要指定一个java.math.RoundingMode枚举值来作为舍入的模式。RoundingMode的取值如下: <table> <thead> <tr> <th>RoundingMode枚举值</th> <th>解释</th> </tr> </thead> <tbody> <tr> <td>RoundingMode.DOW</td> <td>向零方向舍入(去尾法)</td> </tr> <tr> <td>RoundingMode.UP</td> <td>远离零方向舍入</td> </tr> <tr> <td>RoundingMode.FLOO</td> <td>向负无限大方向舍入</td> </tr> <tr> <td>RoundingMode.CEILING</td> <td>向正无限大方向舍入</td> </tr> <tr> <td>RoundingMode.UNNECESSARY</td> <td>不需要舍入,如果用此模式进行舍入,应直接抛出ArithmeticException</td> </tr> <tr> <td>RoundingMode.HALF_UP</td> <td>向最近的整数舍入,其中x.5远离零方向舍入</td> </tr> <tr> <td>RoundingMode.HALF_DOWN</td> <td>向最近的整数舍入,其中x.5向零方向舍入</td> </tr> <tr> <td>RoundingMode.HALF_EVEN</td> <td>向最近的整数舍入,其中x.5向相邻的偶数舍入</td> </tr> </tbody> </table> > 实数运算方法 <table> <thead> <tr> <th>运算</th> <th>IntMath里面方法</th> <th>LongMath里面方法</th> <th>BigIntegerMath里面方法</th> </tr> </thead> <tbody> <tr> <td>除法</td> <td>divide(int, int, RoundingMode)</td> <td>divide(long, long, RoundingMode)</td> <td>divide(BigInteger, BigInteger, RoundingMode)</td> </tr> <tr> <td>2为底的对数</td> <td>log2(int, RoundingMode)</td> <td>log2(long, RoundingMode)</td> <td>log2(BigInteger, RoundingMode)</td> </tr> <tr> <td>10为底的对数</td> <td>log10(int, RoundingMode)</td> <td>log10(long, RoundingMode)</td> <td>log10(BigInteger, RoundingMode)</td> </tr> <tr> <td>平方根</td> <td>sqrt(int, RoundingMode)</td> <td>sqrt(long, RoundingMode)</td> <td>sqrt(BigInteger, RoundingMode)</td> </tr> </tbody> </table> > 实数运算部分Guava还另外提供了一些有用的运算函数 <table> <thead> <tr> <th>运算</th> <th>IntMath里面方法</th> <th>LongMath里面方法</th> <th>BigIntegerMath里面方法</th> </tr> </thead> <tbody> <tr> <td>最大公约数</td> <td>gcd(int, int)</td> <td>gcd(long, long)</td> <td>gcd(BigInteger)</td> </tr> <tr> <td>取模</td> <td>mod(int, int)</td> <td>mod(long, long)</td> <td>mod(BigInteger)</td> </tr> <tr> <td>取幂</td> <td>pow(int, int)</td> <td>pow(long, int)</td> <td>pow(int)</td> </tr> <tr> <td>是否2的幂</td> <td>isPowerOfTwo(int)</td> <td>isPowerOfTwo(long)</td> <td>isPowerOfTwo(BigInteger)</td> </tr> <tr> <td>阶乘*</td> <td>factorial(int)</td> <td>factorial(int)</td> <td>factorial(int)</td> </tr> <tr> <td>二项式系数*</td> <td>binomial(int, int)</td> <td>binomial(int, int)</td> <td>binomial(int, int)</td> </tr> </tbody> </table> > \*阶乘和二项式系数的运算结果如果溢出,则返回MAX\_VALUE # 三 浮点数运算 # JDK已经比较彻底地涵盖了浮点数运算,但Guava在DoubleMath类中也提供了一些有用的方法。 <table> <thead> <tr> <th>运算</th> <th>DoubleMath方法</th> </tr> </thead> <tbody> <tr> <td>判断该浮点数是不是一个整数</td> <td>isMathematicalInteger(double)</td> </tr> <tr> <td>舍入为int;对无限小数、溢出抛出异常</td> <td>roundToInt(double, RoundingMode)</td> </tr> <tr> <td>舍入为long;对无限小数、溢出抛出异常</td> <td>roundToLong(double, RoundingMode)</td> </tr> <tr> <td>舍入为BigInteger;对无限小数抛出异常</td> <td>roundToBigInteger(double, RoundingMode)</td> </tr> <tr> <td>2的浮点对数,并且舍入为int,比JDK的Math.log(double) 更快</td> <td>log2(double, RoundingMode)</td> </tr> </tbody> </table> -------------------- 关于Guava属性运算的一些帮助类就这些。使用非常简单。我们就不举例了。
还没有评论,来说两句吧...