views:

64

answers:

2

This seems horrible inefficient. Can someone give me a better Ruby way.

def round_value
  x = (self.value*10).round/10.0 # rounds to two decimal places
  r = x.modulo(x.floor) # finds remainder
  f = x.floor

  self.value = case
  when r.between?(0, 0.25)
    f
  when r.between?(0.26, 0.75)
    f+0.5
  when r.between?(0.76, 0.99)
    f+1.0
  end
end
+2  A: 

Multiply the number by two.

round to whole number.

Divide by two.

(x*2.0).round / 2.0

In a generalized form, you multiply by the number of notches you want per whole number (say round to .2 is five notches per whole value). Then round; then divide by the same value.

(x*notches).round / notches
JoshD
if you divide by 2 it will truncate due to integer division. I also initially had this problem in my solution :) Divide by 2.0 instead.
Peter
@Peter: Thanks! :)
JoshD
@Peter Thanks. @JoshD Thanks for the added explanation. Makes sense.
Poor Lil Rich Boy
+3  A: 
class Float
  def round_point5
    (self*2).round / 2.0
  end
end

A classic problem: this means you're doing integer rounding with a different radix. You can replace '2' with any other number.

Peter
As this solution adds the method to the Ruby-Class itself, you can use it like this: `(2.45).round_point5` or `x.round_point5`
giraff
class Decimal - is that a Rails thing? And what is 'value'?
steenslag
woah, thanks @steenslag - fixed the value thing which was blatently wrong. I also changed Decimal to Float, because while there is a Decimal class (and the OP mentions decimal in the title), that's probably not what they meant now that you mention it...
Peter