Table of Contents
Memorized the way to round down number to the nth decimal places in Ruby.
The number like 0.81235 (Float) has function floor
, which round down the number to zeal number, can’t round down to some decimal places.
Environment
- Ruby 2.2.3p173
- OS: Ubuntu 15.04
Solution
I detected 3 ways below.
Use BigDecimal
BigDecimal has the function floor
, which can round down to decimal number. When it comes to create BigDecimal object, String parameter is required.
1 2 3 4 5 |
require 'bigdecimal' def dec_floor(num, n) BigDecimal.new(num.to_s).floor(n).to_f end |
Move up decimal point and down
If you want to round down to nth decimal number, multiple ( 10^n ) and round down and divide it by ( 10^n ).
1 2 3 4 5 6 7 8 9 |
def dec_floor(num, n) 1.upto(n) do num *= 10 end num.floor 1.upto(n) do num /= 10 end end |
Round after subtraction
Map the number which is equal to or more than 0.1 and less than 0.2, to the number which is equal to or more than 0.05 and less than 0.15, and round it. Then it’s rounded down 2nd decimal number.
1 2 3 |
def dec_floor(num, n) (num - 0.5 * 0.1 ** n).round(n) end |
When the argument num
is positive, the result is correct. But the argument num
is zero, the result is incorrect.
The following code is true for argument num equal to or more than zero.
1 2 3 |
def dec_floor(num, n) (num + 0.5 * 0.1 ** n).round(n) - 0.1 ** n end |
But this has another problem. dec_floor(0.01, 2)
returns 0.009999999999999998
.
Bad Way
Convert to String with sprintf
sprintf
rounds the number and makes String. It’s not round down.
1 |
sprintf("%.3f", 1.66666666666) # => 1.667 |
It’s rounding off, so subtract half and use sprintf
makes rounded down number, but I don’t recommend.