【Java】0除算とInfinityの仕組みを解説|経験の浅い方でも分かるサンプル付き

お疲れ様です。はるさらと申します。

Javaで数値計算をしていると「0で割ったらどうなるの?」という
疑問が出てくることがあります。

特に整数型ではエラーになるのに、浮動小数点型ではエラーにならず
InfinityNaN が返る
ため、混乱しやすいポイントです。

この記事では、Javaにおける0除算とInfinityの挙動を整理し、
サンプルコードを交えながら分かりやすく解説します。
経験の浅い方がつまずきやすい点や、
実務での注意点についても触れていきます。


Javaでの0除算の基本挙動

整数型の場合

intlong などの整数型で0除算をすると、必ず例外が発生します。

public class IntDivisionExample {
    public static void main(String[] args) {
        int a = 10;
        int b = 0;
        System.out.println(a / b);
    }
}

実行結果:

Exception in thread "main" java.lang.ArithmeticException: / by zero

整数では0除算は数学的に定義されないため、
Javaでは 実行時エラー(ArithmeticException) が投げられます。

浮動小数点型の場合

一方で doublefloat では、0除算をしても
エラーにはならず、特殊な値が返ります。

public class DoubleDivisionExample {
    public static void main(String[] args) {
        double a = 10.0;
        double b = 0.0;

        System.out.println(a / b); // Infinity
        System.out.println(-a / b); // -Infinity
        System.out.println(b / b); // NaN
    }
}

実行結果:

Infinity
-Infinity
NaN

  • 正の数 ÷ 0.0 → Infinity
  • 負の数 ÷ 0.0 → -Infinity
  • 0.0 ÷ 0.0 → NaN

このように、浮動小数点型ではIEEE 754の規格に従った挙動になります。


なぜInfinityが返るのか?

Javaの浮動小数点型は IEEE 754規格 に基づいて設計されています。
この規格では、数値の範囲を超えた場合や
0除算をした場合の動作
が定められています。

  • 0で割ったときにエラーを出さずに Infinity を返すのは、
    計算処理を途切れさせないため。
  • ただし NaN(Not a Number)は計算の結果が定義できないケースを示します。

つまり、InfinityやNaNは「異常終了を防ぐ仕組み」でもありますが、
そのまま後続の計算に使ってしまうと不具合につながる
可能性があります。


実務での0除算とInfinityの扱い方

平均値を計算するケース

売上金額を注文件数で割って「平均単価」を出すようなケースを考えてみましょう。

public class AveragePrice {
    public static void main(String[] args) {
        double sales = 100000.0;
        double orders = 0.0;

        double avg = sales / orders;
        System.out.println("平均単価: " + avg);
    }
}

実行結果:

平均単価: Infinity

注文件数が0件の場合にそのまま計算すると、Infinityが返ってしまいます。
これでは業務システムとして正しく動作しているとは言えません。


if文で事前チェックする方法

0除算を防ぐためには、割り算を行う前にチェックを入れるのが基本です。

public class SafeAveragePrice {
    public static void main(String[] args) {
        double sales = 100000.0;
        double orders = 0.0;

        double avg;
        if (orders != 0.0) {
            avg = sales / orders;
        } else {
            avg = 0.0; // デフォルト値を設定
        }
        System.out.println("平均単価: " + avg);
    }
}


三項演算子を使った簡潔な書き方

public class SampleSauce {

	public static void main(String[] args) {
        double sales = 100000.0;
        double orders = 0.0;

        double avg = (orders != 0.0) ? sales / orders : 0.0;
        System.out.println("平均単価: " + avg);
	}
}

シンプルに書けるため、実務でもよく使われるパターンです。


代替手法の比較

try-catchを使う方法

整数除算の場合は例外が出るので、例外処理でカバーすることも可能です。

public class TryCatchDivision {
    public static void main(String[] args) {
        int a = 10;
        int b = 0;

        try {
            System.out.println(a / b);
        } catch (ArithmeticException e) {
            System.out.println("0で割ることはできません: " + e.getMessage());
        }
    }
}

ただし、実務では if文で事前にチェックする方が
可読性もパフォーマンスも良い
とされます。


経験の浅い方が間違えやすいポイント

  • intとdoubleで挙動が違うことを忘れがち
    → intでは例外、doubleではInfinity/NaN。
  • InfinityをそのままDBや画面に出力してしまう
    → 意図しない値がシステムに混入する原因になります。
  • NaNが計算に混ざると全体がNaNになる
    → 例: NaN + 1 = NaN。データがどんどん壊れる可能性があります。

まとめ

  • Javaの整数型で0除算すると ArithmeticException が発生。
  • 浮動小数点型では InfinityNaN が返る。
  • 実務では必ず0チェックを行い、代替値やメッセージを設定する必要がある。
  • InfinityやNaNをそのまま使うと予期せぬ動作につながるため注意が必要。

経験の浅い方ほど「0で割ったらどうなるのか」を軽視しがちですが、
実務では大きなトラブルの原因になります。

この記事のサンプルを参考に、0除算の動きを自分の環境で試しながら
理解を深めていきましょう!

どなたかのお役に立てば幸いです。
それではまたー!