rubyの数値計算で 1.5/0 は計算できるのに、1/0はエラーになる理由はなんででしょうか?
a = 1
b = 1.5
c = 0
p a/c -> divided by 0 (ZeroDivisionError)
p b/c -> Infinity
となりますがなぜでしょうか?
また、この場合 a/cでもb/cと同じ計算結果(Infinity)を返すようにするのにはどうしたら良いのでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答3件
0
ベストアンサー
RubyではInteger同士の/
とFloat同士の/
では動作が異なります。また、/
において右辺と左辺の型(クラス)が異なるが、それぞれNumericのサブクラスであるのインスタンスである場合、coerce
によってより広い表現に合わせるように片方が変換されます。
a = 1
はInteger、b = 1.5
はFloat、c = 0
はIntgerですのので、次のようになります。
a / c
はIntegerとIntegerなので型変換は発生しない。b / c
はFloatとIntegerなので型変換が発生し、右辺はFloatに変換されるため、b / (c.to_f)
とほぼ同じになる。
Integer同士の/
ですが、これは右辺を左辺で割った時の商(Integer)になります。割りきれない場合でも、余りがあるとして、Integerで返します。通常、ゼロで割ることはできませんので、右辺が0
の場合は例外が発生することになります。
対して、Float同士の/
ですが、こちらは余りを無視した右辺を左辺で割った値です。0
をFloatにすると0.0
になりますが、同じくゼロで割っているのだから、こちらもエラーになるのではと思うかも知れませんが、0
と0.0
では意味が異なります。整数の0
は本当にっぴったりのゼロですが、0.0
は正の方向からゼロに極めて近い値([0~とても小さい正の実数]という範囲)を表します。本当は0.00000...(たくさん続く)...0001かも知れませんが、Floatが表現可能な精度を超えてしまうと0.0
になってしまいます。同様に負の方向からとして-0.0
([とても小さい負の実数~0]という範囲)が存在します。そのためRubyでは、0.0
で割るということは、ゼロに極めて近い値とみなし、そのような値で正の数を割ったときは、無限大(Infinity)を返すと言うことです。もし、-0.0
であれば、ちゃんと負の無限大を返します。
※ 浮動小数点数の除算における0.0
の扱いは言語によって異なります。例えばPythonでは無限大ではなくゼロ除算のエラーが発生します。
a / c
でも同じような計算をさせる場合は、どちらかをFloatにしてください。to_f
で変換するか、Floatをあらわすリテラルにすべきでしょう。
投稿2018/09/23 13:05
編集2018/09/23 13:09総合スコア21735
0
Infinityという表示は、Float::INFINITY
というFloatクラスの定数です。整数同士の除算でFloatクラスの値になることは無いので、意図的に変更する必要があります。
Ruby
1x = begin 2 a / c 3 rescue ZeroDivisionError 4 Float::INFINITY 5 end 6とか、 7x = c==0 ? Float::INFINITY : a/c
投稿2018/09/23 11:51
総合スコア84557
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ruby
1p 1.0/0 -> Infinity 2p 1/0.0 -> Infinity 3p 1.fdiv(0) -> Infinity
投稿2018/09/23 05:13
編集2018/09/23 05:28総合スコア13528
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/09/26 13:19