0

我正在使用 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_valueBigDecimal 写入数据库之前如何限制它的精度以确保它尊重数据库约束?

谢谢!

4

2 回答 2

4

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

IEEE 单精度浮点的 epsilon(误差)约为 6e-08

GPS 和地理编码不是那么详细,即使您处于 179.9996 度。

如果您正在制作高度详细的 200 比例地形图或类似的东西,您可能已经知道必须使用高精度投影,如通用横向墨卡托或兰伯特等,因为您超出了近似的极限地球作为一个球体。但是,如果您正在开发商店查找器类型的应用程序,您不需要、不想要也无法获得这种精度。

如果您必须在 Ruby 程序中使用小数,请在存储到 mySQL 之前转换为浮点数。

这是 Randall Munroe 对地理坐标精度的解释。

在此处输入图像描述

于 2011-01-20T23:34:02.913 回答
0

我会尝试类似的东西

new_value = number_with_precision(your_value.to_f, :precision => 13)
于 2011-01-21T08:09:34.537 回答