

プログラミング初学者です。

Rubyにて、  
「記憶域xに100が、記憶域yに3が格納されている。除算演算子"/"を使用せずに、x ÷ y の解  
を求め、記憶域zに格納せよ。」

という参考書の問題がどうしても解けずにいます・・・。  
その参考書が滅茶苦茶でして、答えの通りにプログラムを書いてもエラーが出てしまい、非常にモヤモヤしています。。。  
一度正しいソースコードを見て、理解を深めたいです。

回答よろしくお願いいたします。


CC BY-SA 4.0
2018-10-25T14:01:58.907
49658
2018-11-09T15:50:25.817
2018-10-28T07:38:05.430
5519
30695
question
ruby
Rubyにて、除算演算子「/」を使用せずに割り算をするプログラム


# 横着編

`/`を使うなと言うことであれば、別名の`div`を使えばいいだけです。

[code]

    x = 100
    y = 3
    z = x.div(y)
    puts z
    
[/code]

# 実装編

上ではあまりにも横着なので`/`を実装しましょう。

[code]

    def my_div(m, n)
      m.step(n, -n).count
    end
    x = 100
    y = 3
    z = my_div(x, y)
    puts z
    
[/code]

この実装には問題があります。除数が0の場合と、被除数と除数のどちらかまたは両方が負の場合を考慮していないと言うことです。除数が0の場合は`/`と同じく`ZeroDivisionError`例外を発生することにします。また、負の場合ですが、剰余がある場合の負の整数の除法は割りきれる場合を除き一意に決まりません。剰余が必ず正になるのか、除数または被除数と同一の符号になるかで商が変わるからであり、どのように実装するかはプログラミング言語によって異なります。ここでは、Rubyの動作と同じ、つまり、除数と同一符号になるようにします。

[code]

    def my_div(m, n)
      raise ZeroDivisionError if n.zero?
      return my_div(-m, -n) if n.negative?
      return -my_div(-m + n - 1, n) if m.negative?
      m.step(n, -n).count
    end
    x = 100
    y = 3
    z = my_div(x, y)
    puts z
    
[/code]

負の計算はちょっと怪しいですので、間違いがあったらごめんなさい。実装方法は一つではありません。`+`や`-`、`*`等を使って求める方法もありますので、自分で考えてみましょう。

さて、上の方法は速くありません。計算量はO(m/n)ですので、mが大きい場合はかなりの時間がかかってしまうからです。小学校で習う割り算の仕方を応用すればもっと高速な処理ができるはずですし、さらにビット演算を用いた方法もあるようです。高速な実装については、きっと、誰かが回答してくれるかと思います。


CC BY-SA 4.0
2018-10-28T01:52:14.627
49718
2018-10-28T01:52:14.627
7347
49658
answer

[code]

    x = 100
    y = 3
    
    def ans(count, x, y)
      if x - y > y
         ans(count + 1, x - y, y)
      else
         count + 1
       end
    end
    
    puts ans(0, x, y)
    
[/code]


CC BY-SA 4.0
2018-11-09T15:50:25.817
50138
2018-11-09T15:50:25.817
30913
49658
answer