From: Koji Arai Date: 2005-11-11T03:34:01+09:00 Subject: [ruby-dev:27677] Re: Numeric#div 新井です。 In message "[ruby-dev:27676] Re: Numeric#div" on 11 Nov 2005 02:01:29 +0900, Yukihiro Matsumoto wrote: > まつもと ゆきひろです > 今はa.div(b)は > > Integer(a / b) > > を返しています。整数除算の結果と浮動小数点数除算を整数化した > ときで丸め方が違うということのようです。揃えるべきだとは思い > ますが、どっちが望ましいのか私には分かりません。御意見希望。 商を q、余りを r として a/b = q..r のとき、数学的には q = (a/b).floor が普通(?詳しくはないですが)らしいので、Fixnum#div にあわ せて floor で良いように思います。 floor なら q = a.div(b) r = a.modulo(b) [q,r] = a.divmod(b) という対応になるので(下記テスト参照)、divmod のメソッドが div と modulo の結果を返すという点で名前的にもきれいです。 (divmod は div と異なり商に Float を返す場合がありますがまぁ それはその方が実数演算に都合が良いのでしょう・・・か?) def test_div(a, div, b, mod) q = a.send(div, b) r = a.send(mod, b) printf("%5s == %3s * %3s + %4s ... %s : %s\n", a, b, q, r, a == b*q + r, [q,r] == a.divmod(b)) end nums = [[13,4], [13,-4], [-13,4],[-13,-13], [11.5,4], [11.5,-4], [-11.5,4], [-11.5,-4]] nums.each {|a, b| test_div(a, :div, b, :modulo) } このテストを実行すると現状は ruby 1.9.0 (2005-08-29) [i686-linux] 13 == 4 * 3 + 1 ... true : true 13 == -4 * -4 + -3 ... true : true -13 == 4 * -4 + 3 ... true : true -13 == -13 * 1 + 0 ... true : true 11.5 == 4 * 2 + 3.5 ... true : true 11.5 == -4 * -2 + -0.5 ... false : false -11.5 == 4 * -2 + 0.5 ... false : false -11.5 == -4 * 2 + -3.5 ... true : true # ruby のバージョンが古くてすみせん となりますが、div の定義が以下なら class Numeric def div(other) self./(other).floor end end ruby 1.9.0 (2005-08-29) [i686-linux] -:2: warning: method redefined; discarding old div 13 == 4 * 3 + 1 ... true : true 13 == -4 * -4 + -3 ... true : true -13 == 4 * -4 + 3 ... true : true -13 == -13 * 1 + 0 ... true : true 11.5 == 4 * 2 + 3.5 ... true : true 11.5 == -4 * -3 + -0.5 ... true : true -11.5 == 4 * -3 + 0.5 ... true : true -11.5 == -4 * 2 + -3.5 ... true : true となります。 逆に、 r = a.remainder(b) に対応する商を返すメソッドが存在しないので、 div を今の Float#div にあわせて q = a.quo(b).to_i として定義すると remainder 的にきれいと言えばきれいなのです が、Fixnum#/ と Fixnum#div で結果が変わる方が現実的に困る場 合がありそうなのでやはり floor の方で良いのではないでしょう か? 互換性の点ですが、div の使用頻度は低いと思ってますので急いで 1.8 に入れなくても、1.9 で様子見で良いかと思います。 今まで気がつかれてないわけですし。 # もちろん、リファレンスの方では将来変更があることは宣伝して # おくようにします。 後は数学に詳しい方の太鼓判があれば良いかと。 -- 新井康司 (Koji Arai)