我记得我的计算机科学教授说过永远不要使用浮动货币.
原因是IEEE specification defines floats是二进制格式的.基本上,它存储符号、分数和指数来表示浮点数.这就像是二进制的科学符号(比如+1.43*10^2
).正因为如此,不可能准确地将分数和小数存储在浮点中.
这就是为什么有十进制格式.如果你这样做:
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个有效数字.这有助于在精度和速度之间进行权衡.因为他们不需要像速度那样精确,所以他们会使用浮动.
如果你处理的是需要精确的数字,并求和到正确的数字(比如复利和金钱相关的事情),请使用decimal.记住:如果你需要精度,那么你应该始终使用十进制.