【发布时间】: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