【问题标题】:rails float different than databaserails float 与数据库不同
【发布时间】:2021-04-22 14:59:03
【问题描述】:

我不明白为什么我的模型中的浮点值不如数据库中的精确。

我们有这张桌子:

  create_table "materials", force: :cascade do |t|
    # ...
    t.float "tiling_rotation"
  end

当我尝试保存 16 位小数的浮点数时,会发生这种情况:

m = Material.create!(tiling_rotation: 1.5707963267948966)
p m.tiling_rotation # 1.5707963267948966
m.reload
p m.tiling_rotation # 1.5707963267949
p m.id # 1234

此时,我认为我的数据库会中继该值,但是当我检查时,我得到了这个:

select tiling_rotation from materials where id = 1234
-- 1.5707963267948966

MY 数据库列的类型为 double precision

这怎么可能?如何将 ruby 的浮点精度设置为与我的数据库相同?

【问题讨论】:

  • 我不知道是什么导致了浮点精度损失,但看起来你将 90 度存储为弧度。也许您可以通过以度为单位存储“平铺旋转”来避免这个问题?
  • 嗨,我们当然可以。但这并不能解决精度损失问题。
  • 这取决于您存储的值,例如90 可以很容易地准确地存储,即使是作为浮点数。存储½????要困难得多。
  • 当然。我们现在使用度数。但现在我有了另一个属性,称为foo,你猜怎么着?同样的问题。
  • 我的意思是:浮点数是近似值,如果精度不那么重要,您可以使用它们。您的示例中两个数字之间的差异小于 0.0000000000002°。如果这还不够,并且您想要更高的精度,或者可能是 exact 值,那么浮点数可能不是正确的数据类型。而且使用非理性的表示并不容易。

标签: ruby-on-rails ruby postgresql optimization


【解决方案1】:

从一点点阅读 ActiveRecord,这可能归结为 Ruby 中数据库小数和浮点数之间映射的精度问题。

尝试更改您的数据库架构,使“tiling_rotation”是精度为 16 的小数。参考:Ruby on Rails - How to migrate code from float to decimal?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-21
    • 2016-12-07
    • 1970-01-01
    • 1970-01-01
    • 2021-09-16
    • 2013-04-23
    相关资源
    最近更新 更多