ruby-on-rails - 避免 Rails 4 中的 Float 截断

标签 ruby-on-rails ruby postgresql rails-activerecord

我有一个带有 Float 属性和对应表的 Active Record 模型:

# app/models/test.rb
class Test < ActiveRecord::Base
end

# db/schema.rb
ActiveRecord::Schema.define(version:20150208185300)

  enable_extension "plpgsql"

  create_table "tests", force: true do |t|
    t.datetime "created_at"
    t.datetime "updated_at"
    t.float    "size"
  end

end

当我坚持测试时,一切看起来都很好:

Test.create(size: 271893999999.99997)
#=> #<Test id: 1, created_at: "2015-02-07 19:43:22", updated_at: "2015-02-07 19:43:22", size: 271893999999.99997>

然而,当检索测试的大小时,它返回为截断:

Test.last.size
#=> 271894000000.0

尽管在我创建它时出现了误导性输出,但它在持久化时也被截断了:

Test.last
#=> #<Test id: 1, created_at: "2015-02-07 19:43:22", updated_at: "2015-02-07 19:43:22", size: 271894000000.0>

这个问题让我很困惑,因为我可以在 Ruby 中做以下事情:

a = 123456789.123456789
#=> 123456789.123456789
a.class
#=> Float
a
#=> 123456789.123456789

在 Rails/Postgres 中使用 Float 有什么限制?如果我想要 5 位小数的精度,是否应该使用 Decimal

我正在使用 Rails 4.1.1 和 Postgres 9.3.5

最佳答案

What are the limits of using Float in Rails/Postgres?

PostgreSQL 支持使用标识符floatrealdouble 的 float 。标识符floatreal 是同义词。在大多数计算机上,floatreal 将为您提供至少 6 位小数精度。这就是六位小数精度的样子。

Test.last.size
#=> 271894000000.0
    ^^^^^^

在大多数计算机上,double 将为您提供至少 15 位小数精度。 Ruby's float相当于 PostgreSQL 的 double,而不是 PostgreSQL 的 real

Should I be using Decimal instead if I want the accuracy of 5 decimal points?

短语我想要 5 个小数点的精度 [sic] 不能很好地转换为 float 据类型。当你写这样的东西时

Test.create(size: 271893999999.99997)

您不是在向 PostgreSQL 询问小数点右边的五位数字。您要求 17 位小数精度。 float 据类型不太可能提供那么高的精度。

您需要使用任意精度数据类型来代替 float 。在数据库端,它看起来像

numeric(17, 5)
decimal(17, 5)

这两个声明都为您提供 17 位精度,小数点右侧最多 5 位。

在 Rails 迁移中,您可能会这样做。

add_column :your_table, :your_column, :decimal, :precision => 17, :scale => 5


你在这里看到的

Test.last.size
#=> 271894000000.0
严格来说,

不是截断或舍入。这是“近似误差”。值 271893999999.99997 不在数据库域 float 中,因此 PostgreSQL 使用该域中 最接近的值。该值恰好是 271894000000.0


PostgreSQL numeric data types

关于ruby-on-rails - 避免 Rails 4 中的 Float 截断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28399739/

相关文章:

ruby-on-rails - Ruby:如何迭代散列并根据项目数量做一些不同的事情?

ruby - 使用 Rails 3 生成并下载 Pdf 文件

java - 使用 Java 插入数据库时​​出现 Postgresql PSQL 异常

python - SELECT 被 OS 信号中断后 Psycopg2 连接不可用

postgresql - 连接到 Azure Postgres 时服务器意外关闭连接

ruby-on-rails - Rails 6 中底层模型更新时如何使 Action Cache 过期?

ruby-on-rails - Golang duplicate rails 设计 gem 密码加密

ruby-on-rails - 在 webrick 服务器的生产模式下运行 rails

ruby-on-rails - 保留、队列和可视化

jquery - 选择2多个: true not working