覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

com.google.common.math.IntMath(LongMath)

Guavacom.google.common.math.IntMath, com.google.common.math.LongMathの利用サンプルです。
数値計算に関する機能を提供するクラスです。

例えば、以下のAPIなどを利用することでオーバーフローをチェックしながら足し算や掛け算などの算術を行うことができます
オーバーフローが発生すると java.lang.ArithmeticException がスローされます

  • IntMath#checkedAdd - intの値範囲のオーバーフローをチェックしながらの加算を行う。
  • IntMath#checkedSubtract - intの値範囲のオーバーフローをチェックしながらの減算を行う。
  • IntMath#checkedMultiply - intの値範囲のオーバーフローをチェックしながらの乗算を行う。
  • LongMath#checkedAdd - longの値範囲のオーバーフローをチェックしながらの加算を行う。
  • LongMath#checkedSubtract - longの値範囲のオーバーフローをチェックしながらの減算を行う。
  • LongMath.checkedMultiply - longの値範囲のオーバーフローをチェックしながらの乗算を行う。

サンプルコードで試したのは以下の通りです。


オーバーフローチェックしながらの加算(int用)

サンプル

System.out.printf("%d + %d = %d\n", 2, 3, IntMath.checkedAdd(2, 3));

try {
    IntMath.checkedAdd(Integer.MAX_VALUE, 1);
} catch (ArithmeticException e) {
    System.out.printf("%d + %d = %s\n", Integer.MAX_VALUE, 1, e.getMessage());
}

実行結果

2 + 3 = 5
2147483647 + 1 = overflow


オーバーフローチェックしながらの減算(int用)

サンプル

System.out.printf("%d - %d = %d\n", 5, 4, IntMath.checkedSubtract(5, 4));

try {
    IntMath.checkedSubtract(Integer.MIN_VALUE, 1);
} catch (ArithmeticException e) {
    System.out.printf("%d - %d = %s\n", Integer.MIN_VALUE, 1, e.getMessage());
}

実行結果

5 - 4 = 1
-2147483648 - 1 = overflow


オーバーフローチェックしながらの乗算(int用)

サンプル

System.out.printf("%d * %d = %d\n", 10, 2, IntMath.checkedMultiply(10, 2));

try {
    IntMath.checkedMultiply(Integer.MAX_VALUE, 5);
} catch (ArithmeticException e) {
    System.out.printf("%d * %d = %s\n", Integer.MAX_VALUE, 5, e.getMessage());
}

実行結果

10 * 2 = 20
2147483647 * 5 = overflow


オーバーフローチェックしながらの加算(long用)

サンプル

System.out.printf("%d + %d = %d\n", 20L, 30L, LongMath.checkedAdd(20L, 30L));

try {
    LongMath.checkedAdd(Long.MAX_VALUE, 1L);
} catch (ArithmeticException e) {
    System.out.printf("%d + %d = %s\n", Long.MAX_VALUE, 1, e.getMessage());
}

実行結果

20 + 30 = 50
9223372036854775807 + 1 = overflow


オーバーフローチェックしながらの減算(long用)

サンプル

System.out.printf("%d - %d = %d\n", 50L, 40L, LongMath.checkedSubtract(50L, 40L));

try {
    LongMath.checkedSubtract(Long.MIN_VALUE, 1L);
} catch (ArithmeticException e) {
    System.out.printf("%d - %d = %s\n", Long.MIN_VALUE, 1L, e.getMessage());
}

実行結果

50 - 40 = 10
-9223372036854775808 - 1 = overflow


オーバーフローチェックしながらの乗算(long用)

サンプル

System.out.printf("%d * %d = %d\n", 100L, 20L, LongMath.checkedMultiply(100L, 20L));

try {
    LongMath.checkedMultiply(Long.MAX_VALUE, 5L);
} catch (ArithmeticException e) {
    System.out.printf("%d * %d = %s\n", Long.MAX_VALUE, 5L, e.getMessage());
}

実行結果

100 * 20 = 2000
9223372036854775807 * 5 = overflow




試したソースコードの全体は以下です。

import com.google.common.math.IntMath;
import com.google.common.math.LongMath;

public class MathClient {

    public static void main(String[] args) {

        // 単純に四則演算するとオーバーフローが起こるが、一応(期待しない)計算結果が返ってくる
        System.out.printf("%d + %d = %d\n", Integer.MAX_VALUE, 1, Integer.MAX_VALUE + 1);
        System.out.printf("%d - %d = %d\n", Integer.MIN_VALUE, 1, Integer.MIN_VALUE - 1);
        System.out.printf("%d * %d = %d\n", Integer.MAX_VALUE, 5, Integer.MAX_VALUE * 5);

        System.out.println("###");

        // オーバーフローをチェックしながら加算・減算・乗算を行う
        // オーバーフローした場合はArithmeticExceptionがスローされる

        // 加算
        System.out.printf("%d + %d = %d\n", 2, 3, IntMath.checkedAdd(2, 3));
        try {
            IntMath.checkedAdd(Integer.MAX_VALUE, 1);
        } catch (ArithmeticException e) {
            System.out.printf("%d + %d = %s\n", Integer.MAX_VALUE, 1, e.getMessage());
        }

        // 減算
        System.out.printf("%d - %d = %d\n", 5, 4, IntMath.checkedSubtract(5, 4));
        try {
            IntMath.checkedSubtract(Integer.MIN_VALUE, 1);
        } catch (ArithmeticException e) {
            System.out.printf("%d - %d = %s\n", Integer.MIN_VALUE, 1, e.getMessage());
        }

        // 乗算
        System.out.printf("%d * %d = %d\n", 10, 2, IntMath.checkedMultiply(10, 2));
        try {
            IntMath.checkedMultiply(Integer.MAX_VALUE, 5);
        } catch (ArithmeticException e) {
            System.out.printf("%d * %d = %s\n", Integer.MAX_VALUE, 5, e.getMessage());
        }

        System.out.println("###");

        // Long値用の同様のクラス(LongMath)を使用した計算

        // 加算
        System.out.printf("%d + %d = %d\n", 20L, 30L, LongMath.checkedAdd(20L, 30L));
        try {
            LongMath.checkedAdd(Long.MAX_VALUE, 1L);
        } catch (ArithmeticException e) {
            System.out.printf("%d + %d = %s\n", Long.MAX_VALUE, 1, e.getMessage());
        }

        // 減算
        System.out.printf("%d - %d = %d\n", 50L, 40L, LongMath.checkedSubtract(50L, 40L));
        try {
            LongMath.checkedSubtract(Long.MIN_VALUE, 1L);
        } catch (ArithmeticException e) {
            System.out.printf("%d - %d = %s\n", Long.MIN_VALUE, 1L, e.getMessage());
        }

        // 乗算
        System.out.printf("%d * %d = %d\n", 100L, 20L, LongMath.checkedMultiply(100L, 20L));
        try {
            LongMath.checkedMultiply(Long.MAX_VALUE, 5L);
        } catch (ArithmeticException e) {
            System.out.printf("%d * %d = %s\n", Long.MAX_VALUE, 5L, e.getMessage());
        }
    }
}