我记得我的CompSci教授说过不要使用浮动货币。
这样做的原因是IEEE规范如何定义二进制格式的浮点数。基本上,它存储符号,分数和指数来表示Float。这就像是二进制的科学记法(类似+1.43*10^2)。因此,不可能在Float中精确存储小数和小数。
这就是为什么存在十进制格式的原因。如果您这样做:
irb:001:0> "%.47f" % (1.0/10)
=> "0.10000000000000000555111512312578270211815834045" # not "0.1"!
而如果你只是做
irb:002:0> (1.0/10).to_s
=> "0.1" # the interprer rounds the number for you
因此,如果您处理的是小数部分,例如复利,甚至可能是地理位置,那么我强烈建议使用十进制格式,因为十进制格式1.0/10恰好是0.1。
但是,应注意,尽管精度较低,但浮标的处理速度更快。这是一个基准:
require "benchmark"
require "bigdecimal"
d = BigDecimal.new(3)
f = Float(3)
time_decimal = Benchmark.measure{ (1..10000000).each { |i| d * d } }
time_float = Benchmark.measure{ (1..10000000).each { |i| f * f } }
puts time_decimal
#=> 6.770960 seconds
puts time_float
#=> 0.988070 seconds
回答
当您不太在乎精度时,请使用float。例如,某些科学模拟和计算最多只需要3或4个有效数字。这对于权衡速度的准确性很有用。由于他们并不需要速度,因此他们会使用float。
如果要处理的数字需要精确并加总为正确的数字(例如,复利和与金钱相关的事物),请使用小数。请记住:如果需要精度,则应始终使用十进制。