I have a numeric value like 30.6355 that represents money, how to round to 2 decimal places?
我有一个像30.6355这样代表金钱的数值,如何舍入到2位小数?
3 个解决方案
#1
20
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.
处理货币时不应使用double或float类型:它们包含太多小数位数和偶尔的舍入错误。金钱可以通过这些漏洞落实,并且在发生错误之后追踪错误将很难。
When dealing with money, use a fixed decimal type. In Ruby (and Java), use BigDecimal.
处理货币时,请使用固定的十进制类型。在Ruby(和Java)中,使用BigDecimal。
#2
13
Ruby 1.8:
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:
Ruby 1.9:
(30.6355).round(2)
In 1.9, round can round to a specified number of digits.
在1.9中,round可以舍入到指定的位数。
#3
0
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
回合(18.00)== 18.0
round(18.99) == 18.99
回合(18.99)== 18.99
round(17.9555555555) == 17.96
回合(17.9555555555)== 17.96
round(17.944444444445) == 17.95
回合(17.944444444445)== 17.95
round(15.545) == 15.55
回合(15.545)== 15.55
round(15.55) == 15.55
回合(15.55)== 15.55
round(15.555) == 15.56
回合(15.555)== 15.56
round(1.18) == 1.18
回合(1.18)== 1.18
round(1.189) == 1.19
回合(1.189)== 1.19
#1
20
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.
处理货币时不应使用double或float类型:它们包含太多小数位数和偶尔的舍入错误。金钱可以通过这些漏洞落实,并且在发生错误之后追踪错误将很难。
When dealing with money, use a fixed decimal type. In Ruby (and Java), use BigDecimal.
处理货币时,请使用固定的十进制类型。在Ruby(和Java)中,使用BigDecimal。
#2
13
Ruby 1.8:
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:
Ruby 1.9:
(30.6355).round(2)
In 1.9, round can round to a specified number of digits.
在1.9中,round可以舍入到指定的位数。
#3
0
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
回合(18.00)== 18.0
round(18.99) == 18.99
回合(18.99)== 18.99
round(17.9555555555) == 17.96
回合(17.9555555555)== 17.96
round(17.944444444445) == 17.95
回合(17.944444444445)== 17.95
round(15.545) == 15.55
回合(15.545)== 15.55
round(15.55) == 15.55
回合(15.55)== 15.55
round(15.555) == 15.56
回合(15.555)== 15.56
round(1.18) == 1.18
回合(1.18)== 1.18
round(1.189) == 1.19
回合(1.189)== 1.19