Jon*_*ard 274 floating-point types ruby-on-rails decimal rails-activerecord
有时,Activerecord数据类型让我感到困惑.呃,经常.对于特定情况,我的一个永恒问题是:
我应该使用
:decimal
或:float
?
我经常遇到这个链接,ActiveRecord :: decimal vs:float?,但答案不够清楚,我无法确定:
我见过许多线程,人们建议不要使用浮点数并始终使用小数.我也看到一些人建议只使用浮动用于科学应用.
以下是一些示例案例:
-45.756688
,120.5777777
,...0.9
,1.25
,1.333
,1.4143
,...我:decimal
过去曾经使用过,但是我发现与BigDecimal
浮点数相比,处理Ruby中的对象是不必要的尴尬.例如,我也知道我可以:integer
用来代表金钱/美分,但它并不适合其他情况,例如精确度随时间变化的数量.
Iur*_* G. 414
我记得我的CompSci教授说永远不要使用花车作为货币.
原因是IEEE规范如何定义二进制格式的浮点数.基本上,它存储符号,分数和指数来表示浮点数.它就像二进制的科学符号(类似+1.43*10^2
).因此,不可能在Float中精确存储分数和小数.
这就是为什么有一个十进制格式.如果你这样做:
irb:001:0> "%.47f" % (1.0/10)
=> "0.10000000000000000555111512312578270211815834045" # not "0.1"!
Run Code Online (Sandbox Code Playgroud)
而如果你这样做
irb:002:0> (1.0/10).to_s
=> "0.1" # the interprer rounds the number for you
Run Code Online (Sandbox Code Playgroud)
因此,如果您正在处理小部分,如复合兴趣,甚至地理位置,我强烈建议使用十进制格式,因为十进制格式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
Run Code Online (Sandbox Code Playgroud)
如果你不太关心精度,请使用float.例如,一些科学模拟和计算仅需要3或4位有效数字.这在折衷速度准确性方面很有用.由于它们不像速度那样需要精度,因此它们会使用浮动.
如果您正在处理需要精确的数字并总结正确的数字(如复利和与金钱相关的事情),请使用小数.记住:如果你需要精度,那么你应该总是使用小数.
rya*_*an0 18
在Rails 3.2.18中,:decimal变为:使用SQLServer时的整数,但它在SQLite中工作正常.切换到:float为我们解决了这个问题.
吸取的教训是"始终使用同构开发和部署数据库!"
Rok*_*san 12
在Rails 4.1.0中,我遇到了将纬度和经度保存到MySql数据库的问题.它不能用float数据类型保存大的分数.我将数据类型更改为十进制并为我工作.
def change change_column :cities, :latitude, :decimal, :precision => 15, :scale => 13 change_column :cities, :longitude, :decimal, :precision => 15, :scale => 13 end
归档时间: |
|
查看次数: |
122819 次 |
最近记录: |