ZeroDivisionError: divided by 0 の原因と直し方
整数を0で割ると、ZeroDivisionErrorという例外が投げられプログラムが止まります。0で割られる可能性がある値は、事前にチェックする必要があります。
エラーメッセージの読み方
main.rb:4:in `/': divided by 0 (ZeroDivisionError)
main.rb- ファイル名
4- 行番号 — 実際にクラッシュした行
/- 発生場所 — <main> ならトップレベル、メソッド名ならそのメソッドの中
ZeroDivisionError- 例外クラス — 何が起きたか。ここを検索するのが最短です
divided by 0- 詳細メッセージ — どの値が問題だったか
このエラーが出る典型パターン
パターン1
1 no_shows = 0 2 attendees = 25 3 total_score = 450 4 puts total_score / no_shows ^
値が0の変数を割り算の分母に使うとZeroDivisionErrorになります。使うべき変数を取り違えていないか確認してください。
直し方: no_shows を attendees にします。
パターン2
1 empty_boxes = 0 2 full_boxes = 10 3 budget = 1000 4 puts budget / empty_boxes ^
整数を0で割るとRubyは例外を投げてプログラムを止めます。0になりうる変数は事前にチェックが必要です。
直し方: empty_boxes を full_boxes にします。
パターン3
1 failed_attempts = 0 2 successful_attempts = 12 3 hits = 96 4 puts hits / failed_attempts ^
変数名が似ていると、0の変数と非0の変数を取り違えやすくなります。
直し方: failed_attempts を successful_attempts にします。
パターン4
1 rest_days = 0 2 travel_days = 6 3 distance = 300 4 puts distance / rest_days ^
0で割る可能性がある値は、計算に使う前に0でないことを確認する必要があります。
直し方: rest_days を travel_days にします。
パターン5
1 empty_groups = 0 2 full_groups = 8 3 people = 40 4 puts people / empty_groups ^
浮動小数点数同士の0除算はInfinityになりますが、整数同士では例外になる点に注意してください。
直し方: empty_groups を full_groups にします。
よくある誤解
「0で割っても Infinity のような特別な値が返ってくるはず」という思い込みは整数同士の割り算には当てはまりません。浮動小数点数(1.0など)同士の割り算ならInfinityになりますが、整数同士では例外が発生します。
実務での勘所
Rubyがこの挙動をInteger(整数)とFloat(浮動小数点数)で使い分けているのは、Floatの1.0/0がIEEE 754という国際規格に従って明確にInfinity(Float::INFINITYという定数と同じ値)を返せるのに対し、整数の世界には「無限大を表す整数値」という概念がそもそも存在しないためです。整数の0除算を例外として明確に拒否することで、「無限大のつもりの整数」のような意味の通らない値が計算の途中に紛れ込むことを防いでいます。