Matt - 2 years ago 60
Ruby Question

# Round a float up if positive, down if negative, to a set number of decimal places

I'm dealing with elapsed hours that should always round up to 1 decimal place, but time in the past needs to round down (so 0.33 hours is 0.4, -0.33 hours is -0.4).

I've briefly written the following but it feels inelegant. Is there a more obvious or more railsy way to do this?

``````def ceil_to_digits(n, digits = 1)
digits = 10.0 ** digits
if n > 0
return (n * digits).ceil / digits
else
return (n * digits).floor / digits
end
end

n = 0.333
ceil_to_digits(n, 1) => 0.4
ceil_to_digits(n, 2) => 0.34

n = -0.333
ceil_to_digits(n, 1) => -0.4
ceil_to_digits(n, 2) => -0.34
``````

`BigDecimal` has various different rounding modes. In this case `ROUND_UP` would solve your problem:

``````require 'bigdecimal'

def ceil_to_digits(n, digits = 1)
BigDecimal.new(n, 0).round(digits, :up)
end

n = 0.333
ceil_to_digits(n, 1) #=> 0.4
ceil_to_digits(n, 2) #=> 0.34

n = -0.333
ceil_to_digits(n, 1) #=> -0.4
ceil_to_digits(n, 2) #=> -0.34
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download