307

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?

mu is too short
  • 426,620
  • 70
  • 833
  • 800
ErwinM
  • 5,051
  • 2
  • 23
  • 35
  • 6
    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. – Phrogz Mar 31 '11 at 16:33

7 Answers7

406

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.

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
mu is too short
  • 426,620
  • 70
  • 833
  • 800
  • 2
    This is the more "rails" answer than the accepted answer. – Sean Ryan Mar 09 '15 at 21:11
  • @muistooshort: i can't replicate it, sorry. I was probably doing something wrong. – Joao Costa Mar 25 '15 at 23:32
  • 5
    @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 Jul 27 '16 at 20:32
  • 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? – stevec Oct 02 '20 at 13:25
  • 1
    @stevec Sorry, I don't know of anything like that. – mu is too short Oct 02 '20 at 17:46
  • 2
    @stevec. I don't know if this works universally, but in all the blocks I've used so far, I've only needed to convert one of the values to a float. That seems to convert everything to a float that it interacts with. – Jeff Zivkovic Sep 18 '22 at 16:09
295

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
Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
vees
  • 3,238
  • 1
  • 16
  • 15
  • 11
    This works but the to_f answer below seems more useful. Is to_f more idiomatic in Ruby? – notapatch Oct 01 '15 at 09:28
  • 15
    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. – jefflunt Aug 05 '16 at 18:20
  • 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. – CTS_AE Jul 26 '21 at 21:23
193

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

9.fdiv(5)  #=> 1.8
Konrad Reiche
  • 27,743
  • 15
  • 106
  • 143
  • 2
    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("eJxlkMEOwiAQRO98hekFuGzxQEwPXvwR01ZqiYHqBk2Tln8XDlWgnDbM25nJonq9NaoD7ZTtR9PigxK09zM7AkgRHieXTYHOsBNf1nklM6B6TuhYpdp+rPgSdiCOi/d/kQ71QBOtAVFLEDly05+UYQ2H+MckL6z0zioDdJG1S9K1K4iQAW66DhnmiqRYKEJFXMByux+XuOJ2XdO60dKsjC7aBtyTL5O5hLk=")) – Chinoto Vokro Jul 28 '16 at 07:15
  • One question, would it preserve the precision like we are using 'decimal'? – Adam Aiken Feb 07 '18 at 03:52
  • Is there any way to obtain integer if the result is integer. Someting like 17/2 = 8.5 and 16/2 = 8? – somenxavier Oct 24 '20 at 15:03
41

You can check it with irb:

$ irb
>> 2 / 3
=> 0
>> 2.to_f / 3
=> 0.666666666666667
>> 2 / 3.to_f
=> 0.666666666666667
Renaud
  • 16,073
  • 6
  • 81
  • 79
26

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.

Rok Kralj
  • 46,826
  • 10
  • 71
  • 80
11

Change the 5 to 5.0. You're getting integer division.

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
Tyler Eaves
  • 12,879
  • 1
  • 32
  • 39
7

Fixnum#to_r is not mentioned here, it was introduced since ruby 1.9. It converts Fixnum into rational form. Below are examples of its uses. This also can give exact division as long as all the numbers used are Fixnum.

 a = 1.to_r  #=> (1/1) 
 a = 10.to_r #=> (10/1) 
 a = a / 3   #=> (10/3) 
 a = a * 3   #=> (10/1) 
 a.to_f      #=> 10.0

Example where a float operated on a rational number coverts the result to float.

a = 5.to_r   #=> (5/1) 
a = a * 5.0  #=> 25.0 
ugandharc18
  • 651
  • 5
  • 7