質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

3回答

2151閲覧

rubyの数値計算で 1.5/0 は計算できるのに、1/0はエラーになる理由

kzd847686

総合スコア53

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2018/09/23 05:06

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ページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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になりますが、同じくゼロで割っているのだから、こちらもエラーになるのではと思うかも知れませんが、00.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
raccy

総合スコア21735

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kzd847686

2018/09/26 13:19

大変勉強になりました!よくわかりました、ありがとうございました。
guest

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

otn

総合スコア84553

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y-doi

2018/09/23 12:04

> 整数同士の除算でFloatクラスの値になることは無いので ozwkさんの回答のように、fdivメソッドを使えば整数同士の除算でもFloatの値になると思うのですがどうでしょうか。
otn

2018/09/23 12:27

それを除算と呼べばそうですね。 / について書いたつもりでした。
y-doi

2018/09/23 12:41 編集

そういう意図でしたか。 ZeroDivisionErrorにならない整数同士による除算なら、otnさんの回答のように整数を返してほしいのかと、fdivを使ってFloatを返してほしいのか用途が違いますね。 失礼しました。
guest

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
ozwk

総合スコア13521

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kzd847686

2018/09/23 05:24

ありがとうございます。小数点以下をつければinfinityになるのはわかっているのですが、その理由がわかりません。また、分母が0のときに毎度”.0”を付け加えるのではなく、なんらか別の方法で対応できるようにしたいのです。
ozwk

2018/09/23 05:29

整数同士の除算は整数になり、整数型にInfinityという状態がないから。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問