Search code examples
rubyfloating-pointnumbers

What's the difference between Float#floor and Float#to_i in Ruby?


I'm learning Ruby, and I'm currently in numbers. So as I understand it, there are five ways (perhaps more) to coerce integers and floats to each other:

  • Integer#to_f: Coerce to a new float
  • Float#ceil: Round up to the nearest integer
  • Float#floor: Round down to the nearest integer
  • Float#round: Round to the nearest integer
  • Float#to_i: Truncate to the nearest integer

What's the difference between "rounding down" and "truncating" to the nearest integer?

When I tested it...

puts 34.4.to_i()
puts 34.4.floor()

... it resulted in the same values:

34
34

Solution

  • The difference is that to_i basically only removes decimals from the float. Whereas float rounds down to the next lower integer. The difference is easier to see when dealing with negative floats:

    -34.4.floor
    #=> -35
    
    -34.4.to_i
    #=> -34
    

    And it might be worth noting that Float#round supports different rounding modes.

    `:up` or `nil`: round away from zero:
    
    2.5.round(half: :up)      # => 3
    3.5.round(half: :up)      # => 4
    (-2.5).round(half: :up)   # => -3
    
    `:down`: round toward zero:
    
    2.5.round(half: :down)    # => 2
    3.5.round(half: :down)    # => 3
    (-2.5).round(half: :down) # => -2
    
    `:even`: round toward the candidate whose last nonzero digit is even:
    
    2.5.round(half: :even)    # => 2
    3.5.round(half: :even)    # => 4
    (-2.5).round(half: :even) # => -2