«1. Обзор

В этой статье мы увидим некоторые полезные математические операции, доступные в библиотеке Guava.

В Guava доступны четыре класса математических утилит:

  1. IntMath – operation on int values
  2. LongMath – operations on long values
  3. BigIntegerMath – operations on BigIntegers
  4. DoubleMath – operations on double values

2. Утилита IntMath

IntMath используется для выполнения математических операций над целыми значениями. Мы пройдемся по списку доступных методов, объяснив каждое их поведение.

2.1. binomial(int n, int k)

Эта функция вычисляет биномиальный коэффициент n и k. Это гарантирует, что результат находится в диапазоне целых чисел. В противном случае он дает Integer.MAX_VALUE. Ответ можно получить по формуле n/k(n-k):

@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. потолокPowerOfTwo(int x)

Вычисляет значение наименьшей степени двойки, которая больше или равна x. Результат n таков, что 2^(n-1) \u003c x \u003c 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. разделить(int p, int q, режим RoundingMode)

Это простое деление, но оно позволяет нам определить режим округления:

@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. то есть произведение первых n положительных целых чисел. Возвращает 1, если n = 0, и возвращает Integer.MAX_VALUE, если результат не соответствует диапазону целых чисел. Результат можно получить как n x (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)

Возвращает наибольшую степень двойки, результат которой меньше или равен x. Результат n таков, что 2^n \u003c x \u003c 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 степенью двойки или нет. Возвращает 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)

Этот 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)

Возвращает логарифм по основанию 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. satinAdd(int a, int b) and Others

Функция суммирования с преимуществом управления любыми переполнениями или потерями, возвращая значение 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-интерфейсы: atomicMultiply, nasatPow и nateSubtract.

2.16. sqrt(int x, режим RoundingMode)

Возвращает квадратный корень из заданного числа. Результат округляется с использованием предусмотренного режима округления:

@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(двойной 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);
}

«Возвращает, является ли x математическим целым числом. Он проверяет, можно ли представить число как целое без потери данных:

5.2. log2(double x)

@Test
public void whenLog2Double_shouldReturnResult() {
    double result = DoubleMath.log2(4);
 
    assertEquals(2, result, 0);
}

Вычисляет логарифм x по основанию 2:

6. Заключение

В этом кратком руководстве мы рассмотрели некоторые полезные математические функции Guava.