【问题标题】:Is this a ruby math function bug - log?这是一个红宝石数学函数错误 - 日志吗?
【发布时间】:2013-11-25 11:33:56
【问题描述】:

下面的代码应该返回true。但是,它返回 false。

(Math.log 1000, 10) == (Math.log10 1000)
==>false

这是ruby(2.0)日志功能的bug吗?

【问题讨论】:

  • "这是语言/编译器错误吗?" --> 99.99% 的情况下,答案是否定的。
  • == 在处理浮点时充其量是棘手的。
  • 那么如何做到这一点呢?

标签: ruby math


【解决方案1】:

进行浮点比较的一种方法是定义一个“足够接近”,例如在 0.001 以内或任何您认为合适的值,然后执行类似的操作

delta = 0.001
log_1 = Math.log 1000, 10
log_2 = Math.log10 1000

close_enough = (log1 - log2).abs < delta

【讨论】:

  • 浮点数比较通常使用 Float::EPSILON,在这种情况下似乎不适合。为什么?
  • 在我的机器上,两次日志操作的差异大约是 EPSILON 值的两倍。我不能说 ruby​​ 是否确保你总是得到相同的结果,或者它是否只是依赖于机器的浮点处理器提供的任何东西。至于为什么两个数学上等价的运算会产生略有不同的值,嗯,这对你来说是浮点数。
  • 在我的机器上有一个差异 4.440892098500626e-16,小于 (2 + 1e-15) * Float::EPSILON。因此,它们应该被平等地考虑。
【解决方案2】:
irb(main):001:0> Math.log10 1000
=> 3.0
irb(main):002:0> Math.log 1000, 10
=> 2.9999999999999996

如您所见,Math.log 不精确,因为浮点的工作方式。

如果你想了解更多关于浮点的信息,你可以去http://floating-point-gui.de/或者搜索谷歌。

【讨论】:

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