2024/05/20

Guava Math

Guava 針對 int, long, BigIntegers, double 提供一些 Math Utility Class methods

IntMath

    @Test
    public void intMath() {
        // binomial(int n, int k)
        // binomial coefficient of n and k
        // 計算 n/k(n-k)
        int result = IntMath.binomial(6, 3);
        assertEquals(20, result);
        // 超過 Integer range 時,會回傳 MAX_VALUE
        result = IntMath.binomial(Integer.MAX_VALUE, 3);
        assertEquals(Integer.MAX_VALUE, result);

        //// ceilingPowerOfTwo(int x)
        // the smallest power of two which is greater than or equal to x
        // x 落在 2 的哪一個指數結果的區間
        // 2^(n-1) < x < 2 ^n
        result = IntMath.ceilingPowerOfTwo(20);
        assertEquals(32, result);

        //// checkedAdd(int a, int b)
        // a+b ,同時會檢查是否結果有 overflow,發生時會 throw ArithmeticException
        result = IntMath.checkedAdd(1, 2);
        assertEquals(3, result);

        Exception exception = assertThrows(ArithmeticException.class, () -> {
            IntMath.checkedAdd(Integer.MAX_VALUE, 100);
        });

        /// divide(int p, int q, RoundingMode mode)
        // 定義 rounding mode 的除法
        result = IntMath.divide(10, 3, RoundingMode.CEILING);
        assertEquals(4, result);
        Exception exception2 = assertThrows(ArithmeticException.class, () -> {
            // 未定義 Rounding Mode  但實際上結果需要 rounding
            IntMath.divide(10, 3, RoundingMode.UNNECESSARY);
        });

        /// factorial(int n)
        // n!   n 階層
        result = IntMath.factorial(5);
        assertEquals(120, result);
        result = IntMath.factorial(Integer.MAX_VALUE);
        assertEquals(Integer.MAX_VALUE, result);

        //// floorPowerOfTwo(int x)
        // 2^n < x < 2 ^(n+1)
        result = IntMath.floorPowerOfTwo(30);
        assertEquals(16, result);

        //// gcd(int a, int b)
        // 最大公因數
        result = IntMath.gcd(30, 40);
        assertEquals(10, result);

        //// isPowerOfTwo(int x)
        // 是否為 2 的倍數
        assertTrue( IntMath.isPowerOfTwo(16) );
        assertFalse( IntMath.isPowerOfTwo(20) );

        //// isPrime(int n)
        // 是否為質數
        assertFalse( IntMath.isPrime(20) );

        //// log10(int x, RoundingMode mode)
        // 以 10 為底 的對數
        result = IntMath.log10(30, RoundingMode.CEILING);
        assertEquals(2, result);
        Exception exception3 = assertThrows(ArithmeticException.class, () -> {
            // 未定義 Rounding Mode  但實際上結果需要 rounding
            IntMath.log10(30, RoundingMode.UNNECESSARY);
        });

        //// log2(int x, RoundingMode mode)
        // 以 2 為底 的對數
        result = IntMath.log2(30, RoundingMode.CEILING);
        assertEquals(5, result);
        Exception exception4 = assertThrows(ArithmeticException.class, () -> {
            // 未定義 Rounding Mode  但實際上結果需要 rounding
            IntMath.log2(30, RoundingMode.UNNECESSARY);
        });

        //// mean(int x, int y)
        //平均
        result = IntMath.mean(30, 20);
        assertEquals(25, result);

        // mod(int x, int m)
        // 餘數
        result = IntMath.mod(30, 4);
        assertEquals(2, result);

        // pow(int b, int k)
        // 指數
        result = IntMath.pow(6, 4);
        assertEquals(1296, result);

        //// saturatedAdd(int a, int b)
        // 控制 overflow/ underflow 時,會改回傳 MAX_VALUE/MIN_VALUE
        result = IntMath.saturatedAdd(6, 4);
        assertEquals(10, result);
        result = IntMath.saturatedAdd(Integer.MAX_VALUE, 1000);
        assertEquals(Integer.MAX_VALUE, result);

        //// sqrt(int x, RoundingMode mode)
        // 平方根
        result = IntMath.sqrt(30, RoundingMode.CEILING);
        assertEquals(6, result);
        Exception exception5 = assertThrows(ArithmeticException.class, () -> {
            // 未定義 Rounding Mode  但實際上結果需要 rounding
            IntMath.sqrt(30, RoundingMode.UNNECESSARY);
        });

    }

LongMath

大部分跟 IntMath 一樣,除了 mod

    @Test
    public void longMath() {
        // Most operations are similar to the IntMath utility
        // 以下是不同的地方

        /// mod(long x, int m) and mod(long x, long m)
        // x mod m
        int result = LongMath.mod(30L, 4);
        assertEquals(2, result);
        long result2 = LongMath.mod(30L, 4L);
        assertEquals(2L, result);
    }

BigIntegerMath

跟 IntMath 類似

DoubleMath

    @Test
    public void doubleMath() {
        //// isMathematicalInteger(double x)
        // 是否為整數
        boolean result = DoubleMath.isMathematicalInteger(5);
        assertTrue(result);
        result = DoubleMath.isMathematicalInteger(5.2);
        assertFalse(result);


        //// log2(double x)
        double result2 = DoubleMath.log2(4);
        assertEquals(2, result2, 0);
    }

References

MathExplained · google/guava Wiki · GitHub

Guide to Mathematical Utilities in Guava | Baeldung

沒有留言:

張貼留言