ArithmeticException の原因は?:Java におけるゼロ除算
Exception in thread "main" java.lang.ArithmeticException: / by zero
というエラーは「ゼロ除算」が原因です。
1 / 0
のようにゼロで割ることは数学では未定義です。
そのため、Java ではゼロ除算を行うと ArithmeticException がスローされたり、Infinity または NaN が返されたりします。
これを避けるには、分母がゼロにならないように条件分岐を追加する必要があります。
目次
事象
次のプログラムでは ArithmeticException が発生します。
サンプルコード
class Scratch {
public static void main(String[] args) {
var n = 1 / 0;
}
}
実行結果
Exception in thread "main" java.lang.ArithmeticException: / by zero
原因
1 / 0
のように「ゼロで割ること」は、ゼロ除算と呼ばれています。
数学では、ある数を 0で割ることは定義されておらず、ゼロ除算の計算結果は未定義です。
Java では、ゼロ除算実行時の挙動は、整数型と浮動小数点数型で異なります:
- 整数型:ArithmeticException がスローされます
- 浮動小数点型:Infinity または NaN が返されます
public class ZeroDivision {
public static void main(String[] args) {
try {
int result = 10 / 0;
System.out.println(result);
} catch (ArithmeticException e) {
System.out.println("0で割ることはできません: " + e.getMessage());
}
}
}
public class FloatZeroDivision {
public static void main(String[] args) {
double result1 = 10.0 / 0;
double result2 = -10.0 / 0;
double result3 = 0.0 / 0;
System.out.println("10.0 / 0 = " + result1); // Infinity
System.out.println("-10.0 / 0 = " + result2); // -Infinity
System.out.println("0.0 / 0 = " + result3); // NaN
}
}
対応方法
ゼロ除算を回避するためには、除算前にゼロ除算が発生しないように条件分岐を追加します。
例えば、タスクの進捗率を計算するメソッドについて考えてみましょう。 タスクの進捗率は、次の数式で計算する仕様とします:
- タスク進捗率 = (完了したタスク数 / 全体のタスク数) * 100
このとき、全体のタスク数が 0 の場合にゼロ除算が発生する可能性があります。 そこで、全体のタスク数が 0 の場合には、進捗率を 0 として返すように条件分岐を追加します。
public int calculateProgress(int completed, int total) {
if (total == 0) {
// 全タスク数が0の場合、進捗率を0%として扱う
return 0.0;
}
return ((double) completed / total) * 100;
}
まとめ
- Java において、整数型でのゼロ除算は ArithmeticException がスローされます
- 浮動小数点数型でのゼロ除算は Infinity または NaN が返されます
- ゼロ除算を回避するためには、除算前にゼロ除算が発生しないように条件分岐を追加します