Ruby Float Round错误Bug?

Nat*_*han 0 ruby floating-point unit-testing rounding-error

当我尝试对下面的类进行单元测试时,我得到以下舍入错误:

class TypeTotal
    attr_reader  :cr_amount,  :dr_amount,
                 :cr_count,  :dr_count

    def initialize()
        @cr_amount=Float(0);    @dr_amount=Float(0)
        @cr_count=0;            @dr_count= 0
    end

    def increment(is_a_credit, amount, count=1)
        case is_a_credit        
         when true
            @cr_amount = Float(amount)+ Float(@cr_amount)
            @cr_count += count
         when false
            @dr_amount = Float(amount)+ Float(@dr_amount)
            @dr_count += count
        end
    end
end
Run Code Online (Sandbox Code Playgroud)

单元测试:

require_relative 'total_type'
require 'test/unit'

class TestTotalType < Test::Unit::TestCase 
  #rounding error
  def test_increment_count()
    t = TypeTotal.new()
       t.increment(false, 22.22, 2)       
       t.increment(false, 7.31, 3) 
     assert_equal(t.dr_amount, 29.53)    
  end
end
Run Code Online (Sandbox Code Playgroud)

输出:

  1) Failure:
test_increment_count(TestTotalType) [total_type_test.rb:10]:
<29.529999999999998> expected but was
<29.53>.

1 tests, 1 assertions, 1 failures, 0 errors, 0 skips
Run Code Online (Sandbox Code Playgroud)

我正在使用Floats,因为它在Pick Axe书中被推荐用于美元值,因为它们不应该通过舍入错误有效.

我正在运行ruby 1.9.2p290 (2011-07-09) [i386-mingw32]Windows 7 64位Home和Windows XP 32位Pro.

我试过了

  • 将我的变量转换为浮点数
  • 删除+ =并拼写增量

行为似乎是随机的:

  • 12.22 + 7.31的作品
  • 11.11 + 7.31不起作用
  • 11.111 + 7.31的作品

任何想法都出错了?

Jon*_*eet 5

你确定这是给出的建议吗?我期望的建议是使用浮动,恰恰是因为他们使用二进制浮点运算,所以容易出现舍入误差.从Float文档:

Float对象使用本机架构的双精度浮点表示来表示不精确的实数.

如果您能引用您所指的确切建议,那将有所帮助.

我建议你BigDecimal改为使用,或者使用隐式单位为"分"或"数百分"或类似的整数.