Why is division in Ruby returning an integer instead of decimal value?

192,094

Solution 1

It’s doing integer division. You can make one of the numbers a Float by adding .0:

9.0 / 5  #=> 1.8
9 / 5.0  #=> 1.8

Solution 2

It’s doing integer division. You can use to_f to force things into floating-point mode:

9.to_f / 5  #=> 1.8
9 / 5.to_f  #=> 1.8

This also works if your values are variables instead of literals. Converting one value to a float is sufficient to coerce the whole expression to floating point arithmetic.

Solution 3

There is also the Numeric#fdiv method which you can use instead:

9.fdiv(5)  #=> 1.8

Solution 4

You can check it with irb:

$ irb
>> 2 / 3
=> 0
>> 2.to_f / 3
=> 0.666666666666667
>> 2 / 3.to_f
=> 0.666666666666667

Solution 5

You can include the ruby mathn module.

require 'mathn'

This way, you are going to be able to make the division normally.

1/2              #=> (1/2)
(1/2) ** 3       #=> (1/8)
1/3*3            #=> 1
Math.sin(1/2)    #=> 0.479425538604203

This way, you get exact division (class Rational) until you decide to apply an operation that cannot be expressed as a rational, for example Math.sin.

Share:
192,094

Related videos on Youtube

ErwinM
Author by

ErwinM

Updated on June 26, 2020

Comments

  • ErwinM
    ErwinM almost 4 years

    For example:

    9 / 5  #=> 1
    

    but I expected 1.8. How can I get the correct decimal (non-integer) result? Why is it returning 1 at all?

    • Phrogz
      Phrogz about 13 years
      Note that if you're actually using a method to return this value, you don't need to assign it to a variable; simply def method; a - b/8; end would return the result of the calculation from the method, as the last expression in a method call is the return value.
  • Sean Ryan
    Sean Ryan about 9 years
    This is the more "rails" answer than the accepted answer.
  • Joao Costa
    Joao Costa about 9 years
    @muistooshort: i can't replicate it, sorry. I was probably doing something wrong.
  • notapatch
    notapatch over 8 years
    This works but the to_f answer below seems more useful. Is to_f more idiomatic in Ruby?
  • Chinoto Vokro
    Chinoto Vokro over 7 years
    @SeanRyan Why specifically Rails rather than Ruby in general? I don't see why a (Ruby on) Rails developer would do this specific thing any differently than a general Ruby developer. Perhaps I'm just nitpicking semantics and most people just see (Ruby on) Rails and Ruby as synonymous in cases like this.
  • Chinoto Vokro
    Chinoto Vokro over 7 years
    This is the fastest method I tested, the only way to get more performance is to divide operands that are floats to begin with. I've built a prime number generator in Ruby in order to learn the syntax, now I'm optimizing it to learn what works best. Here's the benchmark I put together: require 'base64';require 'zlib';puts Zlib.inflate(Base64.decode64("eJxlkMEOwiAQRO98hekFuGzxQEwPXv‌​wR01ZqiYHqBk2Tln8XDl‌​WgnDbM25nJonq9NaoD7Z‌​TtR9PigxK09zM7AkgRHi‌​eXTYHOsBNf1nklM6B6Tu‌​hYpdp+rPgSdiCOi/d/kQ‌​71QBOtAVFLEDly05+UYQ‌​2H+MckL6z0zioDdJG1S9‌​K1K4iQAW66DhnmiqRYKE‌​JFXMByux+XuOJ2XdO60d‌​KsjC7aBtyTL5O5hLk=")‌​)
  • jefflunt
    jefflunt over 7 years
    The .to_f answer is better if you're dividing two variables that contain integers, e.g. a.to_f / b. If you're literally dividing two hard-coded integers (which is probably weird), then using 9.0 / 5 is fine.
  • Adam Aiken
    Adam Aiken about 6 years
    One question, would it preserve the precision like we are using 'decimal'?
  • Meier
    Meier about 5 years
    The mathn module is deprecated since ruby 2.2
  • stevec
    stevec over 3 years
    Is there a way to ensure all math in a certain block is performed on floats (and where not float, coerced to float) without having to .to_f everything?
  • mu is too short
    mu is too short over 3 years
    @stevec Sorry, I don't know of anything like that.
  • somenxavier
    somenxavier over 3 years
    Is there any way to obtain integer if the result is integer. Someting like 17/2 = 8.5 and 16/2 = 8?
  • CTS_AE
    CTS_AE over 2 years
    Adding a decimal will make it a float, and when you do the division it will cast the integer to a float so that the result is a float. Integer division yields an integer answer. Using to_f on an integer is more explicit, whereas adding a decimal .0 to the integer is more implicit. I would recommend using to_f to be more explicit for anyone reading the code, although it may still not be clear what the intentions are to others.