【问题标题】:Best way to handle Fixed point/ percision decimal in Ruby on Rails在 Ruby on Rails 中处理定点/精度小数的最佳方法
【发布时间】:2011-09-14 19:48:37
【问题描述】:

所以我正在使用 Ruby On Rails 创建一个时间跟踪应用程序,并将时间存储为代表小时数的数字。

由于任何超过 0.01(36 秒)小时的时间都无关紧要,因此我只需要 2 位小数。

我正在使用以浮点数作为列类型的 MySQL 数据库。虽然这在大多数情况下都有效,但我时不时地在计算和舍入浮点数时遇到错误。

我对我的选项进行了一些研究,发现很多人建议使用 BigDecimal。由于我使用了很多使用计算的自定义数据库查询,所以我想知道更改列类型会如何影响这一点。它将其存储为字符串或 yaml,还是 MySQL 原生支持?

或者在 Ruby/Rails 中是否有等效的方法来进行定点十进制运算。

我认为任何方法都需要大量重构,我怎样才能最大程度地避免这种情况?

感谢任何见解。

【问题讨论】:

    标签: mysql ruby-on-rails ruby floating-accuracy fixed-point


    【解决方案1】:

    MySQL 确实具有内置的 BigDecimal 支持。 http://dev.mysql.com/doc/refman/5.1/en/precision-math-decimal-changes.html

    我建议使用它;它在我的 Rails 应用程序中运行良好。让数据库而不是应用程序来处理它会让生活更轻松 - 您可以按照设计的方式使用抽象。

    这是迁移代码:

    change_column :table_name, :column_name, :decimal
    

    参考:Rails migration for change column

    【讨论】:

    • + , :precision=> 5, :scale => 2 到更改栏
    • 这几乎可以无缝运行,我几乎不需要更改应用程序代码。
    【解决方案2】:

    我们实际上已经构建了一个时间跟踪应用程序 (http://www.yanomo.com) 并将我们所有的时间存储为它们代表的小时数,其中 MySQL 作为底层 dbms。对于列类型,我们使用 DECIMAL(precision,scale)。在你的情况下,像 DECIMAL(5,2) 这样的东西会做。在我们的业务逻辑 (JAVA) 中,我们使用 BigDecimal。

    【讨论】:

      【解决方案3】:

      不要将时间存储为代表小时的数字,而是将其存储为代表 36 秒(或者可能是单个秒)增量的数字。

      你不应该需要一个十进制支持类型来做定点,只需在业务逻辑中除以得到小时。

      【讨论】:

        猜你喜欢
        • 2012-06-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-06
        • 1970-01-01
        相关资源
        最近更新 更多