Guava 数学函数简介
1. 概述
在本文中,我们将看到 Guava 库中提供的一些有用的数学运算。
Guava 提供了四个数学实用程序类:
- IntMath – 对 int 值的操作
- LongMath – 长值操作
- BigIntegerMath – BigIntegers上的操作
- DoubleMath – 对双精度值的运算
2. IntMath实用程序
IntMath用于对整数值执行数学运算。我们将通过可用的方法列表来解释它们的每个行为。
2.1. binomial(int n,int k)
此函数计算 n 和 k 的二项式系数。它确保结果在整数范围内。否则,它给出Integer.MAX_VALUE。可以使用公式 n/k(nk) 得出答案:
@Test
public void whenBinomialOnTwoInt_shouldReturnResultIfUnderInt() {
int result = IntMath.binomial(6, 3);
assertEquals(20, result);
}
@Test
public void whenBinomialOnTwoInt_shouldReturnIntMaxIfOVerflowInt() {
int result = IntMath.binomial(Integer.MAX_VALUE, 3);
assertEquals(Integer.MAX_VALUE, result);
}
2.2. ceilingPowerOfTwo(int x)
这将计算大于或等于 x 的 2 的最小幂的值。结果 n 使得 2^(n-1) < x < 2 ^n:
@Test
public void whenCeilPowOfTwoInt_shouldReturnResult() {
int result = IntMath.ceilingPowerOfTwo(20);
assertEquals(32, result);
}
2.3. *checkedAdd(int a, int b)*和其他
此函数计算两个参数的总和。这个提供了一个额外的检查,如果结果溢出则抛出ArithmeticException:
@Test
public void whenAddTwoInt_shouldReturnTheSumIfNotOverflow() {
int result = IntMath.checkedAdd(1, 2);
assertEquals(3, result);
}
@Test(expected = ArithmeticException.class)
public void whenAddTwoInt_shouldThrowArithmeticExceptionIfOverflow() {
IntMath.checkedAdd(Integer.MAX_VALUE, 100);
}
Guava 已经检查了其他三个可能溢出的运算符的方法:checkedMultiply、checkedPow和checkedSubtract。
2.4. divide(int p,int q,RoundingMode.CEILING)
这是一个简单的除法,但允许我们定义舍入模式:
@Test
public void whenDivideTwoInt_shouldReturnTheResultForCeilingRounding() {
int result = IntMath.divide(10, 3, RoundingMode.CEILING);
assertEquals(4, result);
}
@Test(expected = ArithmeticException.class)
public void whenDivideTwoInt_shouldThrowArithmeticExIfRoundNotDefinedButNeeded() {
IntMath.divide(10, 3, RoundingMode.UNNECESSARY);
}
2.5. factorial(int n)
计算前 n 个正整数的乘积 nie 的阶乘值。如果 n = 0,则返回 1,如果结果不适合 int 范围,则返回Integer.MAX_VALUE 。结果可以通过 nx (n-1) x (n-2) x ….. x 2 x 1 获得:
@Test
public void whenFactorialInt_shouldReturnTheResultIfInIntRange() {
int result = IntMath.factorial(5);
assertEquals(120, result);
}
@Test
public void whenFactorialInt_shouldReturnIntMaxIfNotInIntRange() {
int result = IntMath.factorial(Integer.MAX_VALUE);
assertEquals(Integer.MAX_VALUE, result);
}
2.6. floorPowerOfTwo(int x)
返回 2 的最大幂,其结果小于或等于 x。结果 n 使得 2^n < x < 2 ^(n+1):
@Test
public void whenFloorPowerOfInt_shouldReturnValue() {
int result = IntMath.floorPowerOfTwo(30);
assertEquals(16, result);
}
2.7. gcd(int a,int b)
该函数为我们提供了 a 和 b 的最大公约数:
@Test
public void whenGcdOfTwoInt_shouldReturnValue() {
int result = IntMath.gcd(30, 40);
assertEquals(10, result);
}
2.8. isPowerOfTwo(int x)
返回 x 是否为 2 的幂。如果值是 2 的幂,则返回 true,否则返回 false:
@Test
public void givenIntOfPowerTwo_whenIsPowOfTwo_shouldReturnTrue() {
boolean result = IntMath.isPowerOfTwo(16);
assertTrue(result);
}
@Test
public void givenIntNotOfPowerTwo_whenIsPowOfTwo_shouldReturnFalse() {
boolean result = IntMath.isPowerOfTwo(20);
assertFalse(result);
}
2.9.isPrime(int n)
此函数将告诉我们传递的数字是否为素数:
@Test
public void givenNonPrimeInt_whenIsPrime_shouldReturnFalse() {
boolean result = IntMath.isPrime(20);
assertFalse(result);
}
2.10. log10(int x, RoundingMode.CEILING)
此 API 计算给定数字的以 10 为底的对数。使用提供的舍入模式对结果进行舍入:
@Test
public void whenLog10Int_shouldReturnTheResultForCeilingRounding() {
int result = IntMath.log10(30, RoundingMode.CEILING);
assertEquals(2, result);
}
@Test(expected = ArithmeticException.class)
public void whenLog10Int_shouldThrowArithmeticExIfRoundNotDefinedButNeeded() {
IntMath.log10(30, RoundingMode.UNNECESSARY);
}
2.11. log2(int x, RoundingMode.CEILING)
返回给定数字的以 2 为底的对数。使用提供的舍入模式对结果进行舍入:
@Test
public void whenLog2Int_shouldReturnTheResultForCeilingRounding() {
int result = IntMath.log2(30, RoundingMode.CEILING);
assertEquals(5, result);
}
@Test(expected = ArithmeticException.class)
public void whenLog2Int_shouldThrowArithmeticExIfRoundNotDefinedButNeeded() {
IntMath.log2(30, RoundingMode.UNNECESSARY);
}
2.12. mean(int x,int y)
使用此函数,我们可以计算两个值的平均值:
@Test
public void whenMeanTwoInt_shouldReturnTheResult() {
int result = IntMath.mean(30, 20);
assertEquals(25, result);
}
2.13. mod(int x,int m)
返回一个数除以另一个数的余数:
@Test
public void whenModTwoInt_shouldReturnTheResult() {
int result = IntMath.mod(30, 4);
assertEquals(2, result);
}
2.14. pow(int b,int k)
返回 b 的 k 次幂:
@Test
public void whenPowTwoInt_shouldReturnTheResult() {
int result = IntMath.pow(6, 4);
assertEquals(1296, result);
}
2.15. *saturatedAdd(int a, int b)*和其他
一个 sum 函数,通过在发生时分别返回值Integer.MAX_VALUE或Integer.MIN_VALUE来控制任何上溢或下溢:
@Test:
public void whenSaturatedAddTwoInt_shouldReturnTheResult() {
int result = IntMath.saturatedAdd(6, 4);
assertEquals(10, result);
}
@Test
public void whenSaturatedAddTwoInt_shouldReturnIntMaxIfOverflow() {
int result = IntMath.saturatedAdd(Integer.MAX_VALUE, 1000);
assertEquals(Integer.MAX_VALUE, result);
}
还有其他三个饱和 API:saturatedMultiply、saturatedPow和saturatedSubtract。
2.16. sqrt(int x, RoundingMode.CEILING)
返回给定数字的平方根。使用提供的舍入模式对结果进行舍入:
@Test
public void whenSqrtInt_shouldReturnTheResultForCeilingRounding() {
int result = IntMath.sqrt(30, RoundingMode.CEILING);
assertEquals(6, result);
}
@Test(expected = ArithmeticException.class)
public void whenSqrtInt_shouldThrowArithmeticExIfRoundNotDefinedButNeded() {
IntMath.sqrt(30, RoundingMode.UNNECESSARY);
}
3. LongMath实用程序
LongMath具有用于Long值的实用程序。大多数操作都类似于IntMath实用程序,这里只描述了少数例外。
3.1. mod(long x, int m)和mod(long x, long m)
返回 x mod m。x除以m的余数:
@Test
public void whenModLongAndInt_shouldModThemAndReturnTheResult() {
int result = LongMath.mod(30L, 4);
assertEquals(2, result);
}
@Test
public void whenModTwoLongValues_shouldModThemAndReturnTheResult() {
long result = LongMath.mod(30L, 4L);
assertEquals(2L, result);
}
4. BigIntegerMath实用程序
BigIntegerMath用于对BigInteger类型执行数学运算。
这个实用程序有一些类似于IntMath 的方法。
5. DoubleMath 实用程序
DoubleMath实用程序用于对双精度值执行操作。
与BigInteger实用程序类似,可用操作的数量是有限的,并且与IntMath实用程序具有相似性。我们将列出一些仅适用于该实用程序类的特殊功能。
5.1. isMathematicalInteger(Double x)
返回 x 是否为数学整数。它检查数字是否可以表示为整数而不会丢失数据:
@Test
public void givenInt_whenMathematicalDouble_shouldReturnTrue() {
boolean result = DoubleMath.isMathematicalInteger(5);
assertTrue(result);
}
@Test
public void givenDouble_whenMathematicalInt_shouldReturnFalse() {
boolean result = DoubleMath.isMathematicalInteger(5.2);
assertFalse(result);
}
5.2. log2(Double x)
计算 x 的以 2 为底的对数:
@Test
public void whenLog2Double_shouldReturnResult() {
double result = DoubleMath.log2(4);
assertEquals(2, result, 0);
}