Round a ruby float up or down to the nearest 0.05

30,005

Solution 1

Check this link out, I think it's what you need. Ruby rounding

class Float
  def round_to(x)
    (self * 10**x).round.to_f / 10**x
  end

  def ceil_to(x)
    (self * 10**x).ceil.to_f / 10**x
  end

  def floor_to(x)
    (self * 10**x).floor.to_f / 10**x
  end
end

Solution 2

[2.36363636363636, 4.567563, 1.23456646544846, 10.5857447736].map do |x|
  (x*20).round / 20.0
end
#=> [2.35, 4.55, 1.25, 10.6]

Solution 3

In general the algorithm for “rounding to the nearest x” is:

round(x / precision)) * precision

Sometimes is better to multiply by 1 / precision because it is an integer (and thus it works a bit faster):

round(x * (1 / precision)) / (1 / precision)

In your case that would be:

round(x * (1 / 0.05)) / (1 / 0.05)

which would evaluate to:

round(x * 20) / 20;

I don’t know any Python, though, so the syntax might not be correct but I’m sure you can figure it out.

Solution 4

less precise, but this method is what most people are googling this page for

(5.65235534).round(2)
#=> 5.65

Solution 5

Here's a general function that rounds by any given step value:

place in lib:

lib/rounding.rb
class Numeric
  # round a given number to the nearest step
  def round_by(increment)
    (self / increment).round * increment
  end
end

and the spec:

require 'rounding'
describe 'nearest increment by 0.5' do
  {0=>0.0,0.5=>0.5,0.60=>0.5,0.75=>1.0, 1.0=>1.0, 1.25=>1.5, 1.5=>1.5}.each_pair do |val, rounded_val|
    it "#{val}.round_by(0.5) ==#{rounded_val}" do val.round_by(0.5).should == rounded_val end
  end
end

and usage:

require 'rounding'
2.36363636363636.round_by(0.05)

hth.

Share:
30,005

Related videos on Youtube

dotty
Author by

dotty

Hmm not alot really.

Updated on July 09, 2022

Comments

  • dotty
    dotty almost 2 years

    I'm getting numbers like

    2.36363636363636
    4.567563
    1.234566465448465
    10.5857447736
    

    How would I get Ruby to round these numbers up (or down) to the nearest 0.05?

    • glenn jackman
      glenn jackman over 14 years
      You realize those aren't integers, right?
  • Swanand
    Swanand over 14 years
    Darn, you beat be me by a couple of seconds! +1 from me, although I had a slight different version in mind.
  • tvanfosson
    tvanfosson over 14 years
    Nice link. Answer would be better with a summary, though, so it can stand on it's own, especially since the linked code doesn't do exactly what the OP asks, i.e., round to the nearest 0.05, but rounds to a particular decimal place.
  • Irukandji
    Irukandji over 14 years
    In order to get decimals divide by 20.0 -> round(x * 20) / 20.0;
  • Pratik Khadloya
    Pratik Khadloya about 12 years
    For ruby: (7.125 * 20).round / 20.0 => 7.15
  • Rob
    Rob about 12 years
    And worse, b/c the post actually reimplements the built-in ruby function round(number-of-decimal-places), it's a bad idea.
  • Christopher Maujean
    Christopher Maujean about 12 years
    This doesn't round UP to the nearest 0.05 as requested by OP, 2.36.... should be 2.40, not 2.35.
  • sepp2k
    sepp2k about 12 years
    @ChristopherMaujean True, but (despite the title) that's not what the OP asked for. The body of the question says "round these numbers up (or down) to the nearest 0.05". Anyway if you want to round up, use ceil instead of round.
  • Christopher Maujean
    Christopher Maujean about 12 years
    I've edited the title to reflect the question, if I'm allowed, I'll remove my downvote.
  • OpenCoderX
    OpenCoderX almost 12 years
    downvote for only supplying a link, lame... and a link that doesn't even answer the question.
  • Aaron Turner
    Aaron Turner about 11 years
    up vote since it does answer the question and round(x) isn't until ruby 0.9.6.
  • Dmitry Lihachev
    Dmitry Lihachev about 11 years
    5.6355.round(2) != 5.65, but TS wants 5.65
  • Scott Swezey
    Scott Swezey about 11 years
    This solution only rounds the number to two decimal places, it does not return a rounded value to the nearest 0.05 as requested.
  • boulder_ruby
    boulder_ruby almost 10 years
    in some ways you're right, I should delete this answer. But on another level this is a very popular question that gets linked to in searches where people find this answer helpful, so I'm going to keep it visible
  • Jerome
    Jerome over 8 years
    the monkey patching need not be necessary. the technique by multiplying by factor, applying_a_function, then dividing by same factor is what you need. Next quarter-currency_unit? use 4 as the factor and ciel.to_f... and so on...
  • philomory
    philomory about 7 years
    As other people have pointed out, this doesn't actually do what the question asks for...
  • jsmartt
    jsmartt about 6 years
    The ceil_to function does not work consistently. For example, 0.07.ceil_to(2) returns 0.08, but SHOULD be 0.07. The same occurs for 0.14, 0.28, 0.55, 1.09, etc.