[RCR] Floating point division operator /. (or fdiv method)

Discussion in 'Ruby' started by Michael Neumann, Jun 2, 2004.

  1. Hi,

    I know that introducing new syntax into Ruby is probably far from being
    accepted by matz....

    Every now and then I accidentially pass an integer to a method and am
    surprised than I get a wrong result. The reason is that the method
    expected floats as arguments and not integers. These kind of bugs are
    very hard to find, IMHO.

    Imagine the following method:

    def meth(a, b)
    a / b
    end

    It works if a, b or both are floats, but not if both are integers.

    Instead you have to write:

    a.to_f / b

    or

    a / b.to_f

    or

    1.0 * a / b

    ...

    My proposal is to add a /. operator, that treats both arguments as
    floats, so that

    1 /. 2 # => 0.5

    Or alternatively:

    class Float
    alias fdiv /
    end

    class Integer
    def fdiv(divisor)
    self.to_f / divisor
    end
    end

    a.fdiv(b)

    Any comments?

    IMHO, even better would be if / would always mean floating point
    division and an extra // operator would mean integer division, but it's
    to late to change now (even for Ruby 2.0) :)

    Regards,

    Michael
     
    Michael Neumann, Jun 2, 2004
    #1
    1. Advertisements

  2. Hmm. that could be useful.. though I rarely uses floats.

    Watchout slashdot not suis you for sealing their name :)
     
    Simon Strandgaard, Jun 2, 2004
    #2
    1. Advertisements

  3. No the name actually comes from Ocaml's /. operator :)
     
    Michael Neumann, Jun 2, 2004
    #3
  4. Michael Neumann

    Paul Brannan Guest

    Perhaps the operator should occasionally (or often) return return bad
    results or misinformation, in the spirit of slashdot editing practices.
    :)

    Paul
     
    Paul Brannan, Jun 2, 2004
    #4
  5. Maybe you could use the 'mathn' module?
    irb(main):001:0> require 'mathn'
    => true
    irb(main):002:0> 1/1
    => 1
    irb(main):003:0> 1/2
    => 1/2
    irb(main):004:0> 3/2
    => 3/2
    irb(main):005:0> 1+ (1/2)
    => 3/2
    irb(main):006:0> 1.0+ (1/2)
    => 1.5
     
    gabriele renzi, Jun 2, 2004
    #5
  6. Hi --

    But you've still got a "have to write" case -- meaning, when you write
    #meth, above, you still can't just write "a / b". So if the problem
    is that you forget to write "a.to_f" instead of "a", you're still in
    danger of forgetting to write "/." instead of "/".
    I like fdiv better than adding a ./ operator.


    David
     
    David A. Black, Jun 2, 2004
    #6
  7. David has said it all - here are some additional remarks.

    You might better use Kernel#Float because of this:
    TypeError: cannot convert nil into Float
    from (irb):8:in `Float'
    from (irb):8=> 0.0
    I strongly oppose that one: Operators are overloaded and if I have two
    int's I want integer division, if I have to floats I want float division.
    And I don't want that changed, because often code is written with integer
    divisions in mind. All sorts of indexing calculations depend on int math.

    Kind regards

    robert
     
    Robert Klemme, Jun 3, 2004
    #7
  8. And the complementary mod operator would only go to 5 :)

    martin
     
    Martin DeMello, Jun 3, 2004
    #8
  9. Sure, but when at the time of writing #meth, you think parameters a and
    b will always be floats (and of course you don't document it, because
    it's a quick hack :), you'll get in trouble later (e.g. meth(1,2) vs.
    meth(1.0, 2.0)). So you want use fdiv, as you expect the division to be
    a floating point division (and for me that's the usual case).

    Regards,

    Michael
     
    Michael Neumann, Jun 3, 2004
    #9
  10. Hi --

    OK, but what I mean is: given the same problem, you can also solve it
    with to_f, and it should be no more or less difficult to remember than
    remembering to use fdiv. (Assuming I'm following your argument
    correctly.) I'm just making the conservative argument with regard to
    change.


    David
     
    David A. Black, Jun 3, 2004
    #10
  11. Michael Neumann

    Bret Jolly Guest

    We already have .div for integer division. (13.div(7) == 2)
    / has an established meaning in the mathn library: 13/7 is the
    rational number 13/7. Since the standard libraries give wrong
    answers when mathn is not required (and no one seems to have the
    slightest interest in fixing them), the mathn meaning must be
    the standard meaning. NEVER use / for integer division:
    use .div instead.

    I don't like the Ocamlish /. . It's fine for Ocaml, a strongly
    and statically typed language, but it strikes me as alien to the
    spirit of Ruby. I'd rather just use .to_f (as in 13/(7.to_f)) to
    force floating point.

    Regards, Bret
     
    Bret Jolly, Jun 3, 2004
    #11
  12. Michael Neumann

    Bret Jolly Guest

    That should be 13.div(7) == 1, of course. *BLUSH*
     
    Bret Jolly, Jun 3, 2004
    #12
  13. Michael Neumann

    Jim Weirich Guest

    Then your code will break whenever it is used in a program that requires
    "mathn". You should always use div if you want integer division.

    The truth is that Ruby's / operator is broken. Any time a programmer
    uses a / operation, they intend the operation to be either a float
    divide or an int divide, not something that polymorphically switches its
    semantics based on the operands. Anytime you use / to mean int
    division, it will break if given floats (or someone required mathn).
    Anytime you use / to mean float division, it will break if given 2 ints.

    In a perfect world where backward compatibility wasn't an issue, I would
    make / always mean float division and // always mean int division.

    If I were to worry about backward compatibility, leave / as is (and
    never use it!). And then provide specific operators for int and float
    division. /. and // aren't too bad. div and fdiv (as methods, not
    operators) are not bad either.

    I recall in earlier threads on this topic that Matz was uncomfortable
    defining division of integers (exact values) so that it returns an
    inexact result. I think he was implying that a future ruby might return
    rationals for integer division. I think that makes sense.
     
    Jim Weirich, Jun 4, 2004
    #13
  14. Hi,

    In message "Re: [RCR] Floating point division operator /. (or fdiv method)"

    |If I were to worry about backward compatibility, leave / as is (and
    |never use it!). And then provide specific operators for int and float
    |division. /. and // aren't too bad. div and fdiv (as methods, not
    |operators) are not bad either.

    Numeric#div does integer division and Numeric#quo does float (or
    rational if available) division _now_.

    matz.
     
    Yukihiro Matsumoto, Jun 4, 2004
    #14
  15. Michael Neumann

    Paul Brannan Guest

    I strongly disagree. It is mathn that is broken, not the / operator.

    I use / all the time to indicate integer division (provided I'm working
    with integers). My code will not work with mathn and I have no
    intention of going out of my way to uglify my code just to make it
    compatible with a broken library.

    I've said it before and I will say it again. Code that changes builtin
    classes without a really good reason (YAML is one such example) is
    broken. See [ruby-talk:81923] for what I've written in the past on this
    subject.

    If we get selector namespaces in ruby 2.0, then mathn can be rewritten
    such that users can get floating-point division with / in their
    namespace only. Until then I recommend not using mathn.

    Paul
     
    Paul Brannan, Jun 4, 2004
    #15
  16. That's especially true if an existing method's or standard operator's
    behavior is changed.
    Thanks for expressing my feelings about this so well!

    Regards

    robert
     
    Robert Klemme, Jun 4, 2004
    #16
  17. Michael Neumann

    Sam Roberts Guest

    I agree, mathn's / operator is broken, not Ruby's!
    I think that the ability to extend the builtins is amazingly useful, but
    I avoid using it in libraries because I can't do scope control.

    Can somebody point me to a description, or ruby-talk thread, of how this
    "selector" mechanism is going to work? Is it decided? I think its a
    very, very interesting idea.

    Cheers,
    Sam
     
    Sam Roberts, Jun 4, 2004
    #17
  18. Not a good choice of names, IMO, since it's not obvious which is which.
    fdiv is clearer than quo.

    martin
     
    Martin DeMello, Jun 4, 2004
    #18
  19. Michael Neumann

    Paul Brannan Guest

    Paul Brannan, Jun 4, 2004
    #19
  20. Hi,

    In message "Re: [RCR] Floating point division operator /. (or fdiv method)"

    |> Numeric#div does integer division and Numeric#quo does float (or
    |> rational if available) division _now_.
    |
    |Not a good choice of names, IMO, since it's not obvious which is which.
    |fdiv is clearer than quo.

    fdiv is not good either, since it may return rational.

    matz.
     
    Yukihiro Matsumoto, Jun 4, 2004
    #20
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.