Reputation: 266940
I have a numeric value like 30.6355 that represents money, how to round to 2 decimal places?
Upvotes: 4
Views: 5820
Reputation: 1519
This will round for some useful cases - not well written but it works! Feel free to edit.
def round(numberString)
numberString = numberString.to_s
decimalLocation = numberString.index(".")
numbersAfterDecimal = numberString.slice(decimalLocation+1,numberString.length-1)
numbersBeforeAndIncludingDeciaml = numberString.slice(0,decimalLocation+1)
if numbersAfterDecimal.length <= 2
return numberString.to_f
end
thingArray = numberString.split("")
thingArray.pop
prior = numbersAfterDecimal[-1].to_i
idx = numbersAfterDecimal.length-2
thingArray.reverse_each do |numStr|
if prior >= 5
numbersAfterDecimal[idx] = (numStr.to_i + 1).to_s unless (idx == 1 && numStr.to_i == 9)
prior = (numStr.to_i + 1)
else
prior = numStr.to_i
end
break if (idx == 1)
idx -= 1
end
resp = numbersBeforeAndIncludingDeciaml + numbersAfterDecimal[0..1]
resp.to_f
end
round(18.00) == 18.0
round(18.99) == 18.99
round(17.9555555555) == 17.96
round(17.944444444445) == 17.95
round(15.545) == 15.55
round(15.55) == 15.55
round(15.555) == 15.56
round(1.18) == 1.18
round(1.189) == 1.19
Upvotes: 0
Reputation: 11640
Ruby 1.8:
class Numeric
def round_to( places )
power = 10.0**places
(self * power).round / power
end
end
(30.6355).round_to(2)
Ruby 1.9:
(30.6355).round(2)
In 1.9, round can round to a specified number of digits.
Upvotes: 13
Reputation: 638
You should not use double
or float
types when dealing with currency: they have both too many decimal places and occasional rounding errors. Money can fall through those holes and it'll be tough to track down the errors after it happens.
When dealing with money, use a fixed decimal type. In Ruby (and Java), use BigDecimal.
Upvotes: 20