0
Help us understand the problem. What are the problem?

posted at

updated at

Ruby の加減乗除は他の言語と同じ,なの?

加減乗除などの基本的な数値演算について書かれた Ruby の初心者向け記事で,よく

Ruby の算術演算(or 四則演算,加減乗除 etc)は他の言語と変わりません。

などとして,例えば

puts 20 + 30 # => 50
puts 16 - 9  # => 7
puts 20 * 3  # => 60
puts 60 / 3  # => 20
puts 10 % 3  # => 1

といったコードサンプルが書かれていることがあります。
Qiita でも,年に何本かそういう記事が書かれています。

もちろん「変わる(違いがある)」かどうかは「他の言語」が何であるかによるわけですが,まあ「わりとメジャーな普通っぽい多くの言語」くらいのつもりで書かれているのだと思います。

和・差・積はともかくとして,商と剰余は要注意ですよ。これは言語によってさまざまです。

このコードサンプルの除算で,割り切れるような数が選ばれているのは意図してでしょうか。
割り切れない数の場合にどうなるかは知っておきたいところです。
Ruby では,被除数(割られる数)と除数(割る数)がともに Integer オブジェクトの場合,/ による除算は「整除」になります。整除は剰余(余り)を考慮に入れる割り算のことですね。したがって結果は必ず整数になります。

puts 10 / 4 # => 2

一方が Integer オブジェクトでない場合は整除になりません。

puts 10.0 / 4 # => 2.5
puts 10r / 4  # => 5/2

上の例で,10r というのは数学的に 10 に等しい Rational オブジェクト(有理数オブジェクト)です。「分母が 1 で分子が 10 の有理数オブジェクト」ですね。
10r / 4 の結果は「2 分の 5」という Rational オブジェクトになります。

このような,整数オブジェクト同士の / による除算が整除になるのは Ruby の著しい特徴です。JavaScript も PHP も

10 / 4

は浮動小数点数の 2.5 になります1

さて,整除についてしっかり把握すべき点が一つあります。それは被除数・除数の少なくとも一方が負数の場合にどうなるか,です。
Ruby は除数が正のとき,被除数の符号に関わらず,整商(整除における商)は 0 以上,除数未満の値になります。これは数学的には最もなじみのある自然な整除の定義ですが2,プログラミング言語ではむしろ少数派ではないかと思います。

puts -10 / 4 # => -3
puts 10 / -4 # => -3
puts -10 / -4 # => 2

もう一つ大事なことは,Ruby の除算は / によるものだけではない,ということです。
まず,被除数・除数の型に関わらず浮動小数点数の商が欲しい場合,Numeric#fdiv が使えます。

puts 10.fdiv(4) # => 2.5

一方,被除数・除数の型に関わらず整商が欲しい場合,Numeric#div を使います。

puts 10.0.div(4.0) # => 2
puts 3.5.div(1.5)  # => 2

上のコードの二つ目の例のように,整数でない数同士でも整除が得られる,ということが大事ですね3

逆に,被除数・除数の型に関わらず普通の商が欲しい場合,Numeric#quo を使います。

puts 10.quo(4) # => 5/2
puts 10.0.quo(4) # => 2.5

Integer 同士の場合,割り切れるなら Integer で返し,割り切れない場合は Rational で返すのが特徴です。

以上で分かるとおり,60 / 3 の結果だけ見て「Ruby の除算は他の言語と同じ」などと言うわけにはいかないのです。

除算について述べるなら剰余についても述べるべきですが,この記事で注意喚起したかったことは以上で尽きているので割愛します。

  1. PHP では,被除数・除数が共に整数型で,かつ割り切れるときに限り結果が整数型になり,そうでないときは浮動小数点数になるのだそうです。

  2. しかし,これが整除の唯一の定義ではありません。整除の定義はいくつもあります。

  3. 数学では整除は整数の世界だけで考えることが多いのですが,小学校の算数では小数の整除を教えています。小数の整除に意味があることは,「3.5 m の紐から 1.5 m の紐が何本取れるか」を考えれば明らかでしょう。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
0
Help us understand the problem. What are the problem?