Guavaのcom.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()); } } }