Ruby 两个非常接近的浮点数不相等

Ruby 两个非常接近的浮点数不相等,ruby,floating-point,Ruby,Floating Point,在IRB中: 同时仅显示检查值: 0.9999999999999998 == 1.0 # => false 0.99999999999999998 == 1.0 # => true 不幸的是,在我的例子中,我的程序创建的值是第一个值,所以我在编写一个测试用例来验证值是否等于1时遇到了麻烦 我将在以下选项之间做出选择: 在应用程序代码中添加round调用,但是应用程序已经在工作,我只是无法测试 在测试代码中添加round调用 你推荐的方法是什么?是否有一种方法可以配置我的程序,将小

在IRB中:

同时仅显示
检查
值:

0.9999999999999998 == 1.0
# => false
0.99999999999999998 == 1.0
# => true
不幸的是,在我的例子中,我的程序创建的值是第一个值,所以我在编写一个测试用例来验证值是否等于1时遇到了麻烦

我将在以下选项之间做出选择:

  • 在应用程序代码中添加
    round
    调用,但是应用程序已经在工作,我只是无法测试
  • 在测试代码中添加
    round
    调用

  • 你推荐的方法是什么?是否有一种方法可以配置我的程序,将小数点后15个9的0视为等于1.0?这感觉有点令人沮丧,因为小数点后的16个9似乎是截止点——我只差一个

    阅读这篇关于如何比较小浮点差异的文章:

    我将他们提出的解决方案转换为Ruby:

    0.9999999999999998
    # => 0.9999999999999998
    0.99999999999999998
    # => 1.0
    
    输出:

    f1 = 0.99999999999999998
    f2 = 0.9999999999999998
    f3 = 0.999999999999998
    
    [f1, f2, f3].each { |f|
      p f.eq_epsilon?(1.0)
      p 1.0.eq_epsilon?(f)
    }
    
    puts "--------------"
    
    [f1, f2, f3].each { |f|
      p f.eq_reldif?(1.0)
      p 1.0.eq_reldif?(f)
    }
    

    但是,可能需要更多的测试来确保它满足您的所有要求。

    阅读这篇关于如何比较小的浮点差异的文章:

    我将他们提出的解决方案转换为Ruby:

    0.9999999999999998
    # => 0.9999999999999998
    0.99999999999999998
    # => 1.0
    
    输出:

    f1 = 0.99999999999999998
    f2 = 0.9999999999999998
    f3 = 0.999999999999998
    
    [f1, f2, f3].each { |f|
      p f.eq_epsilon?(1.0)
      p 1.0.eq_epsilon?(f)
    }
    
    puts "--------------"
    
    [f1, f2, f3].each { |f|
      p f.eq_reldif?(1.0)
      p 1.0.eq_reldif?(f)
    }
    

    但是,可能需要更多的测试来确保它满足您的所有要求。

    您已经证明,IRB将十进制浮点值解释为具有固定精度的Float类型,而不是具有任意精度的BigDecimal类型。这并没有说明你的程序做了什么或应该做什么,也没有说明你的测试做了什么或应该做什么。同样要注意的是,对浮点数进行精确(不相等)的比较是不合适的。使用任意精度的数字并不能真正改变这一点。如果您需要特定的建议,那么您需要明确您要测试的谓词是什么。@JohnBollinger我想知道是否有一种方法可以将Float配置为
    0.99999999998==1.0
    。就像我说的,看起来这个值(15个9)与我需要的精度(16个9)只有一个差。我已经开始查看类中的常量-我尝试更改
    EPSILON
    DIG
    ,但没有效果。不,@maxpleaner,您无法调整浮点的精度。这与机器硬件和ABI的特点有关。“不幸的是,我的程序创造的价值是第一个”——也许你不应该首先使用浮动。如何计算该值?您已经展示了IRB将十进制浮点值解释为具有固定精度的Float类型,而不是具有任意精度的BigDecimal类型。这并没有说明你的程序做了什么或应该做什么,也没有说明你的测试做了什么或应该做什么。同样要注意的是,对浮点数进行精确(不相等)的比较是不合适的。使用任意精度的数字并不能真正改变这一点。如果您需要特定的建议,那么您需要明确您要测试的谓词是什么。@JohnBollinger我想知道是否有一种方法可以将Float配置为
    0.99999999998==1.0
    。就像我说的,看起来这个值(15个9)与我需要的精度(16个9)只有一个差。我已经开始查看类中的常量-我尝试更改
    EPSILON
    DIG
    ,但没有效果。不,@maxpleaner,您无法调整浮点的精度。这与机器硬件和ABI的特点有关。“不幸的是,我的程序创造的价值是第一个”——也许你不应该首先使用浮动。如何计算该值?