在Ruby中不使用BigDecimal将美分转换为美元字符串

在Ruby中不使用BigDecimal将美分转换为美元字符串,ruby,string,floating-point,bigdecimal,Ruby,String,Floating Point,Bigdecimal,我想在Ruby中正确地将美分转换为美元。我永远不必用零碎的钱工作 不必使用BigDecimal,是否可以正确执行此操作(无浮点错误) 例如,美分对美元 "99" => "0.99" "324" => "3.24" 以下内容似乎有效,但是否正确 (cents.to_i/100.0).to_s (cents.to_i/100.0).to_s 更新:我注意到上面的这句话不起作用,如果我个人不想重新发明这个

我想在Ruby中正确地将美分转换为美元。我永远不必用零碎的钱工作

不必使用
BigDecimal
,是否可以正确执行此操作(无浮点错误)

例如,美分对美元

"99" => "0.99"
"324" => "3.24"
以下内容似乎有效,但是否正确

(cents.to_i/100.0).to_s
(cents.to_i/100.0).to_s

更新:我注意到上面的这句话不起作用,如果我个人不想重新发明这个特定的轮子,而去使用它。从文件中(添加了重点):

特征

提供一个Money类,该类封装有关 一定数量的货币,如其价值和货币

提供一个Money::Currency类,该类封装有关 货币单位

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

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

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

有 将货币和货币字符串解析为 对应的货币/货币对象。

As:看看金钱宝石吧

例如:

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.to_i/100.0).to_s
乍一看,还可以,但是:

cents = '10'
p (cents.to_i/100.0).to_s # -> '0.1'
你没有两个数字

备选方案:

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

<>你也可以考虑使用理性。但是,我不确定在sprintf运行时它们是否会转换为浮动:

"%.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"

如果它们已经被叮咬,您可以使用字符串操作,完全绕过数字问题:

# 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"

没有精度问题,没有浮点,没有bignum,没有理性,没有技巧,没有聪明。需要一些简单的修改来处理负值,但这与已有的一样简单。

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

->
price.to_i.fdiv(100)


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

取决于所需的精度。如果你对分精度没问题,那就用金钱宝石吧。事实上,金钱宝石可以执行除法。这很公平。正如我所说,OP没有告诉我们太多他打算做什么,但我个人不想在别人已经做了的情况下处理所有复杂的金钱问题。谢谢。我想我只是想要一个简单、高效的解决方案(即,不必加载库或使用gem)。感谢您提供了一个解决方案,而不仅仅是说“使用这个gem”。@DanaWoodman,如果
cents
=
“10287349283923497624861294712974892742837833”
,那么@knut提供的“替代”解决方案就不起作用了。请参阅中@muistooshort提供的解决方案。很好!谢谢此解决方案甚至可以在以下情况下工作:
cents
=
“10287349283923497624861294712974892742837833”
(也可以)。你知道(或者你能找到)任何值(对于
cents
)这个解决方案不起作用吗?这很酷,但我认为
cents.to_I.fdiv(100)
cents.to_I/100.0
基本相同。我想如果你要除以的整数不是文字,那么fdiv可能会有用。无论如何,如果
美分
=“10287349283923497624861294712974892742837833”,这两种解决方案都不起作用。请参阅中@muistooshort提供的解决方案。