PullMonkey Blog

31 Jan

Rounding to the nearest number in Ruby


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 

Filed under: development, Home, ruby Tags:


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

  1. By Tim Harrison on Jan 31, 2008 | Reply

    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. By charlie on Jan 31, 2008 | Reply

    @Tim – great addition, thanks for posting it 🙂

  3. By Hamoth on Jan 31, 2008 | Reply

    What is modulus and where are you putting this code?

  4. By charlie on Jan 31, 2008 | Reply

    @Hamoth – modulus returns the remainder of a division. For example if I have modulus(5/2) I will get 1. modulus(10/7), I will get 3. In rails, this code would go in its own file under RAILS_ROOT/config/initializers/. Otherwise, you would just put this code in its own file and require it in your other source code.

  5. By Henrik N on Sep 3, 2009 | Reply

    Tim, I think for rounding to nearest, you’ll find this is easier 🙂

    
    def roundnearest(multiple=10)
      (self/multiple.to_f).round * multiple
    end
    
  6. By Ben on Feb 5, 2011 | Reply

    Thanks for this, exactly what I needed to round an int up to nearest 500 🙂

Sorry, comments for this entry are closed at this time.