java.lang.ArithmeticException は、計算ができないときの例外です。 原因はメッセージで決まります。

メッセージ 何をしたか 直し方
/ by zero 整数(int・long)を 0 で割った、0 で余りを出した 割る数が 0 のときの扱いを先に決める
Non-terminating decimal expansion; no exact representable decimal result. BigDecimal で、割り切れない割り算(1÷3)を桁数の指定なしで行った divide(値, 桁数, 丸め方)
Rounding necessary BigDecimal で、丸めが要るのに丸め方を指定しなかった setScale(桁数, 丸め方)
Division by zero / Division undefined BigDecimal を 0 で割った(0÷0 は undefined) 0 のときの扱いを先に決める
integer overflow Math.addExact などで、int・long の範囲を超えた long・BigDecimal にする

確認環境:OpenJDK 21.0.10(Linux)で再現しました(確認日 2026年10月12日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「ArithmeticExceptionの直し方|/ by zero他」

/ by zero:整数を 0 で割った

int total = 100, count = 0;
System.out.println(total / count);
Exception in thread "main" java.lang.ArithmeticException: / by zero
    at S.main(S.java:1)

整数の割り算と余り(%)は、0 で割ると例外になります。 一方、小数(double)は例外にならず、Infinity や NaN になりました。 例外が出ないぶん、気づかずに画面へ NaN が出ることがあります。

計算 結果
10 / 0(int) ArithmeticException: / by zero
10 % 0(int) ArithmeticException: / by zero
10L / 0L(long) ArithmeticException: / by zero
10.0 / 0(double) Infinity(例外にならない)
0.0 / 0(double) NaN(例外にならない)

よくある形:0件の平均

件数が 0 のときに平均を出す処理が一番多い原因です。配列やリストが空のとき、合計 / 件数 が 0 / 0 になります。

int avg = sum / list.size();   // ← 空のとき / by zero

0件のときの扱いを決めて書き分けます。

// 0件なら「平均なし」を返す
OptionalDouble avg = list.stream().mapToInt(Integer::intValue).average();
System.out.println(avg.isPresent() ? avg.getAsDouble() : "データなし");

// 0件なら 0 として扱う、と決めた場合
int avg2 = list.isEmpty() ? 0 : sum / list.size();

average() は、空のとき空の OptionalDouble を返すので、0 で割ることがありません。 「0件のとき平均は 0 か、表示しないか」は画面や帳票の仕様なので、決めてから書きます。

Non-terminating decimal expansion:BigDecimal の割り切れない割り算

BigDecimal の divide(値) は、答えを正確に表せないとき(1÷3 = 0.333…)に例外になります。 割り切れる 1÷4 は 0.25 と返りました。

new BigDecimal("1").divide(new BigDecimal("3"));
Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
    at java.base/java.math.BigDecimal.divide(BigDecimal.java:1783)
    at S2.main(S2.java:2)

直し方は、小数点以下の桁数と丸め方を指定することです。

BigDecimal r1 = BigDecimal.ONE.divide(new BigDecimal("3"), 2, RoundingMode.HALF_UP);   // 0.33
BigDecimal r2 = BigDecimal.ONE.divide(new BigDecimal("3"), MathContext.DECIMAL64);     // 0.3333333333333333
指定 意味 向いている場面
divide(値, 2, RoundingMode.HALF_UP) 小数点以下2桁、四捨五入 金額・率など、桁を決めて見せる値
divide(値, 2, RoundingMode.DOWN) 小数点以下2桁、切り捨て 端数を切り捨てる決まりのとき
divide(値, MathContext.DECIMAL64) 有効数字16桁 途中の計算で、あとで丸めるとき

「1件あたりの単価」「按分」など、割り算の結果をお金として扱うときは、桁数と丸め方は仕様で決まっているはずです。どこで丸めるか(明細ごとか、合計か)は、関連記事「金額計算の端数処理設計:消費税の丸め仕様とDECIMAL型の選び方」で扱っています。

Rounding necessary:丸め方を指定していない

setScale(桁数) だけを書き、桁を減らすのに丸めが要ると、Rounding necessary になります。 2.0 を整数にするのは丸め不要なので例外になりませんが、1.5 は丸めが要るので例外でした。

書き方 結果
new BigDecimal("2.0").setScale(0) 2
new BigDecimal("1.5").setScale(0) ArithmeticException: Rounding necessary
new BigDecimal("1.5").setScale(0, RoundingMode.HALF_UP) 2
new BigDecimal("1.5").intValueExact() ArithmeticException: Rounding necessary
BigDecimal yen = price.multiply(rate).setScale(0, RoundingMode.DOWN);   // 円未満切り捨て

入るデータによって、例外が出たり出なかったりするのがこの例外のやっかいな点です。テストでは割り切れる値だけでなく、端数が出る値も入れて確かめます。

Division by zero / Division undefined:BigDecimal を 0 で割った

計算 メッセージ
BigDecimal.TEN.divide(BigDecimal.ZERO) Division by zero
BigDecimal.ZERO.divide(BigDecimal.ZERO) Division undefined

割る数が 0 になりうるなら、compareTo で先に確かめます。BigDecimal は equals だと 0 と 0.00 を別物として扱うので、0 かどうかは signum() か compareTo で比べます。

if (divisor.signum() == 0) {
    return BigDecimal.ZERO;   // 0 のときの扱いは仕様で決める
}
return amount.divide(divisor, 2, RoundingMode.HALF_UP);

integer overflow:範囲を超えたことに気づくための例外

普通の + や * は、int の範囲を超えても例外になりません。 黙って違う値(マイナスの値など)になります。Math.addExact などを使うと、超えたときに integer overflow で止まります。

計算 結果
100_000 * 100_000(int) 1410065408(例外なし、間違った値)
Math.multiplyExact(100_000, 100_000) ArithmeticException: integer overflow
Math.addExact(Integer.MAX_VALUE, 1) ArithmeticException: integer overflow
Math.toIntExact(3_000_000_000L) ArithmeticException: integer overflow

この例外は「直す」より「気づかせてくれた」ものです。 超えるのが正しい値なら、long か BigDecimal に変えます。金額の合計・件数×単価・ミリ秒の計算は、int を超えやすい計算です。

例外にならない計算の注意

計算 結果 注意
-7 % 3 -1 マイナスの余りはマイナス。0〜2 にしたいなら Math.floorMod(-7, 3)(2)
7 / 2 3 整数の割り算は切り捨て。小数が要るなら 7 / 2.0
0.1 + 0.2 0.30000000000000004 お金は double ではなく BigDecimal

整数の割り算や余りのくわしい動きは、関連記事「Java 割り算の小数・切り捨て・余りまとめ|整数除算と0除算の挙動」で扱っています。

よくある質問

Q. try-catch で ArithmeticException を受けて 0 を返してもいいですか。 A. 0 で割る可能性が分かっているなら、catch より先に if で分けるほうが、読む人に意図が伝わります。catch すると、ほかの原因の ArithmeticException(桁あふれなど)までまとめて 0 になります。

Q. RoundingMode.HALF_UP と HALF_EVEN の違いは? A. HALF_UP はいわゆる四捨五入、HALF_EVEN は「ちょうど半分のときは偶数のほうへ」丸めます(2.5 → 2、3.5 → 4)。どちらを使うかは仕様で決めます。BigDecimal の使い方は、関連記事「Java BigDecimalの使い方|金額計算の丸めと比較の注意点」で扱っています。

Q. new BigDecimal(0.1) と new BigDecimal("0.1") は違いますか。 A. 違います。double から作ると 0.1000000000000000055511151231257827… のような値になります。文字列か BigDecimal.valueOf(0.1) で作ります。

Q. スタックトレースに自分のコードの行が無いときは? A. ライブラリの中で計算している場合です。Caused by: やスタックトレースの下のほうから、自分のクラス名が出る行を探します。読み方は関連記事「Javaスタックトレースの読み方|Caused byの意味と原因の探し方」で扱っています。

まとめ

  • / by zero は整数を 0 で割った。0件の平均が多い。average() か isEmpty() で分ける
  • Non-terminating decimal expansion は BigDecimal の割り切れない割り算。divide(値, 桁数, 丸め方)
  • Rounding necessary は丸め方の指定漏れ。setScale(桁数, 丸め方)
  • double は 0 で割っても例外にならず Infinity・NaN
  • integer overflow は Math.addExact などが範囲超えを知らせたもの。long・BigDecimal へ

参考・出典

確認日はいずれも 2026年10月12日です。

  • Java SE 21 API「ArithmeticException」:https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/ArithmeticException.html
  • Java SE 21 API「BigDecimal」(divide・setScale):https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/math/BigDecimal.html
  • Java SE 21 API「RoundingMode」:https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/math/RoundingMode.html
  • Java SE 21 API「Math」(addExact・multiplyExact・toIntExact・floorMod):https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Math.html
  • Java 言語仕様(Java SE 21)15.17.2 Division Operator /:https://docs.oracle.com/javase/specs/jls/se21/html/jls-15.html#jls-15.17.2

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「ArithmeticExceptionの直し方|/ by zero他」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?