在不使用BigDecimal的情况下将美分转换为美元字符串

时间:2011-09-18 11:53:52

标签: ruby string floating-point bigdecimal

我想在Ruby中正确地将美分转换为美元。我将永远不必使用分数。

是否可以正确执行此操作(没有浮点错误)而无需使用BigDecimal

例如,美分到美元

"99" => "0.99"
"324" => "3.24"

以下似乎有效,但它是否正确?

(cents.to_i/100.0).to_s

5 个答案:

答案 0 :(得分:11)

作为Micheal Kohl already answered:看看金钱宝石。

示例:

require 'money'
Money.use_i18n = false  #https://stackoverflow.com/q/31133229/676874
puts Money.new( 99, 'USD')
puts Money.new(324, 'USD')

  

以下似乎有效,但它是否正确?

(cents.to_i/100.0).to_s

第一眼看,没关系,但是:

cents = '10'
p (cents.to_i/100.0).to_s # -> '0.1'

您没有2位数字。

替代:

p '%.2f' % (cents.to_i/100.0) # -> '0.10'

答案 1 :(得分:5)

如果他们已经蜇了你就可以使用字符串操作并完全绕过数字问题:

# There are, of course, all sorts of ways to do this.
def add_decimal(s)
  pfx = [ '0.00', '0.0', '0.' ]
  if(pfx[s.length])
    s = pfx[s.length] + s
  else
    s = s.dup
    s[-2, 0] = '.'
  end
  s
end

add_decimal('')      #   "0.00" 
add_decimal('1')     #   "0.01" 
add_decimal('12')    #   "0.12" 
add_decimal('123')   #   "1.23" 
add_decimal('1234')  #  "12.34" 
add_decimal('12345') # "123.45"

没有精确问题,没有浮点,没有bignums,没有理性,没有什么棘手,没有什么聪明。需要进行一些简单的修改来处理负值,但这将是已经存在的简单修改。

答案 2 :(得分:4)

就个人而言,我不会尝试重新发明这个特定的轮子并使用money gem。从文档(强调添加):

  

功能

     

提供一个Money类,它封装了有关的所有信息   一定数量的货币,例如其价值和货币。

     

提供Money :: Currency类,它封装了有关a的所有信息   货币单位。

     

将货币值表示为整数,以美分为单位。这个   避免浮点舍入错误。

     

将货币表示为   Money ::货币实例提供高度的灵活性。

     

提供用于从一种货币兑换另一种货币的API。

     

<强>有   能够将货币和货币字符串解析为   相应的货币/货币对象。

答案 3 :(得分:2)

您也可以考虑使用Rational。但是,我不确定它们在sprintf-ed时会被转换为浮点数:

"%.2f" % Rational("324".to_i,100)
#=> "3.24"
"%.2f" % Rational("99".to_i,100)
#=> "0.99"
"%.2f" % Rational("80".to_i,100)
#=> "0.80"
"%.2f" % Rational("12380".to_i,100)
#=> "123.80"

答案 4 :(得分:-1)

您可以为此使用 fdiv。返回两个数相除后的浮点结果

-> price.to_i.fdiv(100)

例如:'123'.to_i.fdiv(100) -> 1.23