- JAVA
ArithmeticExceptionの直し方|/ by zero他
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期連続の黒字決算。