Posted at

int計算のオーバーフロー対策はMath#multiplyExactを使おう

More than 3 years have passed since last update.


tl;dr


  • Java8からはいった Math#multiplyExactメソッド便利

  • 足し算は toIntExactメソッドがある


概要

エンジニアであれば一度ぐらいint*intの計算をしてオーバーフローを起こしたことありますよね?

仕様上はintを超えることはないから絶対平気だよ!! という謎のお告げを信じて書いちゃいますよね。

サンプルコード

public static void main(String[] args) {

int rate = rate();
int point = point();
int total = rate() * point();
System.out.println(String.format("%d x %d = %s", rate, point, total));
}

でも、サービスは進化して仕様が増えて、仕様は忘却の彼方に消えてしまいます。

point()の値が何億とかになってくると、オーバーフローが発生して想定してない値になってうぁあぁぁあぁぁと頭抱えたくなるわけです。

こんなときにMath#multiplyExactをつかうわけです

JavaDocにあるように、


ArithmeticException - if the result overflows an int


なので、オーバーフローしたら安全に例外を出してくれます。

public static void main(String[] args) {

int rate = rate();
int point = point();
int total = Math.multiplyExact(rate(), point());
System.out.println(String.format("%d x %d = %s", rate, point, total));
}
// Exception in thread "main" java.lang.ArithmeticException: integer overflow
// at java.lang.Math.multiplyExact(Math.java:867)

ちなみに似たようなものに Math#toIntExactなどもがあるので、これも相当便利。

Java8素敵。そしてこれを教えてくれたIntelliJ IDEAも素敵。