2011-01-20 66 views
0

我使用Rails 3.0.3在MySQL数据库中存储了一些纬度和经度。下面是我用(与给定精度注意十进制值)创建表迁移的一部分:Ruby BigDecimal和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的精度,然后再将它写入数据库,以确保它遵守数据库约束?

谢谢!

回答

4

在mySQL中,使用FLOAT来存储这些地理坐标。将它们作为高精度小数存储是没有意义的。请记住,1/60度的纬度是海里,所以一英尺(约1/3米)约为3微米。 (3E-06)

为IEEE单精度浮点(错误)的小量约6E-08

GPS和地理编码不是那么详细,甚至当你在179.9996度。

如果你正在制作高度详细的200比例地形地图或类似的东西,你可能已经知道你必须使用高精度的投影,如通用横向墨卡托或兰伯特等,因为你超越了将地球近似为球体的极限。但是,如果你正在做一个商店查找器类型的应用程序,那么你不需要,也不需要,也不会那么精确。

如果您必须在Ruby程序中使用十进制,请在存储到mySQL之前转换为float。

+0

感谢奥利。问题是我后来使用坐标进行计算,所以这就是为什么我使用BigDecimal时,认为Floats可能会在这里返回奇怪的值,不是吗?我会尝试你最后的解决方案,在验证之前转换为浮动。 – Cimm 2011-01-21 23:08:29

+0

@Cimm - 对于这些计算,浮点数可以很好地工作。认真。 – 2011-01-23 01:43:37

0

我会尝试像

new_value = number_with_precision(your_value.to_f, :precision => 13)