我使用Rails 3.0.3在MySQL数据库中存储一些纬度和经度。以下是我用于创建表的迁移的一部分(请注意具有给定精度的十进制值):
create_table :dummies do |t|
t.decimal :something, :precision => 13, :scale => 10
end
以下RSpec示例应说明它出错的地方。
我使用BigDecimal进行一些计算,结果my_value
是一个精度很大的数字(大于迁移中指定的数字)。我将对象存储在数据库中并再次检索它。
将原始值与数据库值进行比较失败,因为它们的精度不同,因此它不再是相同的数字:
it 'should be equals before and after save' do
my_value = BigDecimal('4.123456789') * 5000 # more precise than defined in the migration
dummy = Dummy.new(:something => my_value)
location.save!
Dummy.first.something.should == dummy.something
end
我理解为什么会发生这种情况(MySQL中的小数精度!= BigDecimal)但是有人能告诉我在将数据写入数据库之前如何限制my_value
BigDecimal的精度确保它尊重数据库约束?
谢谢!
答案 0 :(得分:4)
在mySQL中,使用FLOAT存储这些地理坐标。将它们存储为高精度十进制毫无意义。请记住,1/60的纬度是海里,所以一英尺(约1/3米)约为3微度。 (3E-06)
IEEE单精度浮点(错误)的epsilon约为6e-08
即使你处于179.9996度,GPS和地理编码也不那么详细。
如果您正在制作非常详细的200级地形图或类似的地图,您可能已经知道必须使用高精度投影,如通用横向墨卡托或兰伯特等等,因为您已超出限制近似地球为球体。但是,如果你正在做一个商店查找类型的应用程序,你不需要,不想要,也不能得到那种精确度。
如果必须在Ruby程序中使用decimal,请在存储到mySQL之前转换为float。
答案 1 :(得分:0)
我会尝试像
这样的东西new_value = number_with_precision(your_value.to_f, :precision => 13)