Ruby on rails 避免Rails 4中的浮点截断

Ruby on rails 避免Rails 4中的浮点截断,ruby-on-rails,ruby,postgresql,rails-activerecord,Ruby On Rails,Ruby,Postgresql,Rails Activerecord,我有一个活动记录模型,它具有Float属性和相应的表: # 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 "crea

我有一个活动记录模型,它具有
Float
属性和相应的表:

# 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.last
#=> #<Test id: 1, created_at: "2015-02-07 19:43:22", updated_at: "2015-02-07 19:43:22", size: 271894000000.0>
在Rails/Postgres中使用
Float
有什么限制?如果我想要5个小数点的精度,我应该使用
十进制


我正在使用Rails 4.1.1和Postgres 9.3.5

使用
十进制
,并在数据库中指定精度和比例,以便确保计算准确


使用
十进制
并在数据库中指定精度和比例,以便确保计算准确


使用
十进制
并在数据库中指定精度和比例,以便确保计算准确


使用
十进制
并在数据库中指定精度和比例,以便确保计算准确

在Rails/Postgres中使用Float有哪些限制

PostgreSQL支持使用标识符float、real和double的浮点数。标识符float和real是同义词。在大多数计算机上,float和real至少可以提供6位十进制精度。这是六位小数精度的样子

Test.last.size
#=> 271894000000.0
    ^^^^^^
在大多数计算机上,double至少可以提供15位十进制精度。相当于PostgreSQL的double,而不是PostgreSQL的real

如果我想要5个小数点的精度,我应该使用十进制吗

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

Test.create(size: 271893999999.99997)
您没有要求PostgreSQL提供小数点右侧的五位数字。你要求的是17位小数精度。浮点数据类型不太可能提供那么高的精度

您需要使用任意精度的数据类型,而不是浮点数。在数据库方面,它看起来像

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


在Rails/Postgres中使用Float有哪些限制

PostgreSQL支持使用标识符float、real和double的浮点数。标识符float和real是同义词。在大多数计算机上,float和real至少可以提供6位十进制精度。这是六位小数精度的样子

Test.last.size
#=> 271894000000.0
    ^^^^^^
在大多数计算机上,double至少可以提供15位十进制精度。相当于PostgreSQL的double,而不是PostgreSQL的real

如果我想要5个小数点的精度,我应该使用十进制吗

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

Test.create(size: 271893999999.99997)
您没有要求PostgreSQL提供小数点右侧的五位数字。你要求的是17位小数精度。浮点数据类型不太可能提供那么高的精度

您需要使用任意精度的数据类型,而不是浮点数。在数据库方面,它看起来像

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


在Rails/Postgres中使用Float有哪些限制

PostgreSQL支持使用标识符float、real和double的浮点数。标识符float和real是同义词。在大多数计算机上,float和real至少可以提供6位十进制精度。这是六位小数精度的样子

Test.last.size
#=> 271894000000.0
    ^^^^^^
在大多数计算机上,double至少可以提供15位十进制精度。相当于PostgreSQL的double,而不是PostgreSQL的real

如果我想要5个小数点的精度,我应该使用十进制吗

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

Test.create(size: 271893999999.99997)
您没有要求PostgreSQL提供小数点右侧的五位数字。你要求的是17位小数精度。浮点数据类型不太可能提供那么高的精度

您需要使用任意精度的数据类型,而不是浮点数。在数据库方面,它看起来像

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


在Rails/Postgres中使用Float有哪些限制

PostgreSQL支持使用标识符float、real和double的浮点数。标识符float和real是s