gpt4 book ai didi

ruby-on-rails - Rails 通过引入浮点逻辑来搞乱 BigDecimals

转载 作者:IT王子 更新时间:2023-10-29 06:32:18 26 4
gpt4 key购买 nike

我正在尝试使用 rails,我发现了一些奇怪的东西。为了存储货币值,我使用典型的十进制数据类型,事件记录将其转换为 BigDecimal。我认为这是精确的,我想避免 float 学的奇怪行为。但是当我将 99.99 存储到数据库时一切正常,但是当事件记录加载记录时它会失去精度并转换为 99.9899999999 之类的东西。这看起来像是一个 float 问题。

我做了一些测试,发现像这样创建一个 BigDecimal b = BigDecimal.new("99.99") 会导致一个“干净”的变量,但以这种方式构建它 b = BigDecimal.new(99.99) 会导致“我想避免的“不干净”版本。

我猜想,当从数据库加载记录时,ActiveRecord 会用中间 float 重建 BigDecimal。这不是我想要的,我想知道是否可以避免。

ruby 版本 1.9.3p0 rails 3.2.9sqlite 3.7.9

最佳答案

您的问题是您使用的是 SQLite,而 SQLite 本身不支持 numeric(m,n) 数据类型。来自fine manual :

1.0 Storage Classes and Datatypes

Each value stored in an SQLite database (or manipulated by the database engine) has one of the following storage classes:

  • NULL. The value is a NULL value.
  • INTEGER. The value is a signed integer, stored in 1, 2, 3, 4, 6, or 8 bytes depending on the magnitude of the value.
  • REAL. The value is a floating point value, stored as an 8-byte IEEE floating point number.
  • TEXT. The value is a text string, stored using the database encoding (UTF-8, UTF-16BE or UTF-16LE).
  • BLOB. The value is a blob of data, stored exactly as it was input.

进一步阅读该页面以了解 SQLite 的类型系统是如何工作的。

你的 99.99 在你的 Ruby 代码中可能是 BigDecimal.new('99.99') 但它几乎可以肯定是 REAL99.99 (即一个八字节的 IEEE 浮点值)在 SQLite 中,然后就到了附近。

所以在你的开发环境中切换到一个更好的数据库;特别是,在您要部署的任何数据库之上进行开发。

关于ruby-on-rails - Rails 通过引入浮点逻辑来搞乱 BigDecimals,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13830402/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com