Rounding to the nearest number in Ruby

January 31st, 2008 by charlie

A while ago, I was taking a look at a problem on the rails forum. This post was submitted to find the best solution to round any number to the nearest multiple of 10. For example, this method would take the number 6 and return 10, or the number 29 and return 30. So the first thing that popped into my mind was modulus. We can use modulus to determine how far we are from the nearest multiple of 10. Meaning that if we are given 19 and we want to know how close we are to the nearest 10, we can simple do 19 % 10, which will return 9, and 10 - 9 is 1, so we are 1 away from the nearest 10 spot. Here is that method, assuming only Fixnum, so it is implemented as an extension of the Fixnum class:
1
2
3
4
5
6
7
8

class Fixnum
  def roundup
    return self if self % 10 == 0   # already a factor of 10
    return self + 10 - (self % 10)  # go to nearest factor 10
  end
end 

While this did the job, it was suggested that it would be better if things happened.
  1. Use the Numeric class (this class encompasses Float, Fixnum and Integer)
  2. Don't limit the method to just the nearest 10, have it as a parameter
  3. And an added bonus - rounddown()

Here is the resulting code (defaulting to 10):
1
2
3
4
5
6
7
8
9
10

class Numeric
  def roundup(nearest=10)
    self % nearest == 0 ? self : self + nearest - (self % nearest)
  end
  def rounddown(nearest=10)
    self % nearest == 0 ? self : self - (self % nearest)
  end
end 

Well that is pretty cool, here is some sample output from using this method:
1
2
3
4
5
6
7
8
9

puts 2.roundup    #=> 10
puts 23.roundup   #=> 30
puts 20.roundup   #=> 20
puts 45.roundup   #=> 50
puts 156.roundup  #=> 160 
puts 156.34.roundup   #=> 160.0
puts 16.34.roundup    #=> 20.0
puts 81.1234.roundup  #=> 90.0 

2 Responses to “Rounding to the nearest number in Ruby”

  1. Tim Harrison Says:
    How about this addition?

    def roundnearest(nearest=10)
    up = roundup(nearest)
    down = rounddown(nearest)
    if (up-self) < (self-down)
    return up
    else
    return down
    end
    end
  2. charlie Says:

    @Tim - great addition, thanks for posting it :)

Leave a Reply

Check here to see how to submit syntax highlighted code to the comments.