使用Rails的Mysql浮点精度问题

时间:2011-08-15 16:39:38

标签: mysql ruby-on-rails activerecord

对于我目前的项目,我不得不重新设计旧数据库并保留所有旧数据。我写了一个rake任务来复制所有数据(它不是一个直接的一对一映射),除了一些浮点值之外,它工作正常。

某些值在旧的Mysql数据库中定义为浮点数。问题是我的ActiveRecord查询返回舍入值而不是实际值。如果我在旧数据库上运行查询,我会得到:

mysql> select mean, format(mean, 10) from example_table;
+---------+------------------+
| mean    | format(mean, 10) |
+---------+------------------+
| 1.10844 | 1.1084357500     |
| 1.10223 | 1.1022269726     |
| 1.11771 | 1.1177104712     |
+---------+------------------+

均值的实际值与时间的格式化值MOST匹配。有时,某些值的有效数字较少,而format(mean, 10)会提供错误的数字(例如,1.1会提供类似1.1000001421的数字)。

在我的rake任务中,我使用以下命令查询旧数据库:

values = ActiveRecord::Base.connection.execute('SELECT mean FROM example_table')

不幸的是,values将包含该舍入值而不是实际值。有没有办法存储实际值而不是舍入值?

我正在使用Mysql Distrib 5.1.51和Rails 3.0.9

澄清:

问题不在于新的数据库精度。在我尝试保存数据之前就出现了问题。

values = ActiveRecord::Base.connection.execute('SELECT mean FROM example_table') #selects from the legacy database

使用该行,返回的每个mean在我访问它时都会被舍入。此时还没有对新数据库做任何事情,所以它不应该与此有任何关系。

换句话说,当我查询mysql时,我希望它返回插入的完全值。那可能是1.0或1.23456789。我不在乎有多少有效数字,我只想要那个确切的值。

在执行我的select语句和AR返回值之间的某处,值被舍入。我试图了解那一点。

2 个答案:

答案 0 :(得分:3)

我自己一直有精确度问题,但我正在使用货币值。为了绕过舍入,我将我的浮点列转换为十进制,指定适合我的应用程序的精度和比例:

def self.up
    change_column :revenues, :amount, :decimal, :precision => 12, :scale => 2
end

如果您知道精度的上限以及小数后需要多少有效数字,那么您可以使用小数方法。此外,当我针对我的测试数据库运行迁移时,我的所有数据都被保留并“修复”了我在应用中看到的怪异。

答案 1 :(得分:-1)

这解释了为什么你永远不应该使用浮点精度 - 浮动是数量。

如果一个人应该在光年中测量到月球的距离 - 它们会有一个分界,但是如果你使用毫微米作为整数,那么你的数字会非常精确 - 对吗?

http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html

之所以,是deci和hexa之间的分数,是不能完全转换的。

当我做XML时,我在进行高精度计算时使用包含分数(除数)的属性 - 例如value =“123456789”divisor =“1000” - 这样可以在不丢失任何图层的情况下顺利处理不同的图层...

在MySQL中我不想列 - 所以十进制表示,是你的答案......