【问题标题】:Compare floats in R比较 R 中的浮点数
【发布时间】:2020-04-22 08:02:30
【问题描述】:

免责声明

我不确定是在这里发布还是在CV 上发布,但在阅读了is on topic on CV 的内容后,我认为它更具体是R,而不是纯粹的统计数据。因此,我把它贴在这里。

问题

引用?.Machine

double.eps
最小的正浮点数x 使得1 + x != 1。如果double.base 为2 或double.rounding 为0,则等于double.base ^ ulp.digits;否则为(double.base ^ double.ulp.digits) / 2。一般2.220446e-16.

因此,我假设all.equal(1 + .Machine$double.eps, 1.0) 返回FALSE。它没有。阅读all.equal 的文档,我看到默认容差是.Machine$double.eps ^ 0.5

很公平,但我观察到一些我不理解的奇怪结果:

isTRUE(all.equal(1.0 + .Machine$double.eps, 1.0, tolerance = .Machine$double.eps)) # TRUE
isTRUE(all.equal(1.0 - .Machine$double.eps, 1.0, tolerance = .Machine$double.eps)) # FALSE
isTRUE(all.equal(0.9 + .Machine$double.eps, 0.9, tolerance = .Machine$double.eps)) # FALSE
isTRUE(all.equal(2.0 + .Machine$double.eps, 2.0, tolerance = .Machine$double.eps)) # TRUE

因此,all.equal 仅正确选择小于 1 的数字的差异。

我能想到的最后一个解释是all.equal 默认情况下会显示在 relative difference scale 上,所以我试图推翻这种行为也没有成功:

isTRUE(all.equal(1.0 + .Machine$double.eps, 1.0, 
                 tolerance = .Machine$double.eps, scale = 1)) # TRUE

显然,我对浮点数在 R 中的工作方式有很大的误解,这导致我想到了这些

问题

  • 如何正确比较 R 中的 2 个数字与“最大”(以浮点精度为单位)精度?
  • 为什么all.equal 的结果对于低于和高于1 的数字不同?
  • [奖励问题]:使用.Machine$double.eps ^ .5 作为默认容差而不是无平方根版本的合理性是什么?是不是简单的把考试放宽了一点?

【问题讨论】:

  • Machine$double.eps 最小正浮点数x 使得1 + x != 1。对于0.1 + x != 0.1,x 小于Machine$double.eps,对于100 + x != 100,x 大于Machine$double.eps
  • 要将 R 中的 2 个数字与“最大”精度进行比较,请正确使用 ==
  • 正如你在这里给出的.Machine$double.eps的容差。
  • Re “[Bonus Question]:使用 .Machine$double.eps ^ .5 作为默认容差而不是无平方根版本的合理性是什么?是不是简单地把测试放宽了一点?”:唯一合理的是很多人用浮点数做简单的事情,只得到一些表现良好的舍入错误,并且不需要区分数字,如果使用实数算术计算,则非常接近但不相等。从本质上讲,这种默认容差只适用于业余爱好者在涉及复杂工作时进行修补和破坏。避免使用它。

标签: r floating-point precision


【解决方案1】:

.Machine$double.eps是1与大于1的最小可表示值的差。0.1与大于0.1的最小可表示值的差小于.Machine$double.eps,100与大于1的最小可表示值的差100 大于.Machine$double.eps。看看:What is the correct/standard way to check if difference is smaller than machine precision?.

.Machine$double.eps

.Machine$double.eps
[1] 2.220446e-16

当您进行计算时,intern sorted 值将约为:

print(1.0 + .Machine$double.eps, 20)
#[1] 1.000000000000000222
print(1.0 - .Machine$double.eps, 20)
#[1] 0.99999999999999977796
print(0.9 + .Machine$double.eps, 20)
#[1] 0.90000000000000024425
print(2.0 + .Machine$double.eps, 20)
#[1] 2

使用 tolerance = .Machine$double.eps all.equal 返回 TRUEFALSE,具体取决于实习生存储值的差异是否大于 tolerance

要比较 R 中的 2 个数字,如果它们的实习生存储相等,请使用 ==

【讨论】:

  • 你的最后一句话没有意义。什么是“最大”精度?永远不要将计算出的浮点数与 == 进行比较。
  • 我把它改成了if the are intern stored equal
  • “最小的正浮点数x 这样1+x != 1.Machine$double.eps 的错误定义,即使文档说明了。正确的定义是它是 1 和大于 1 的最小可表示值之间的差,,在 1 的量级上可表示值之间的距离。这在 IEEE- 中是 2**-52 754 二进制 64。如果定义不正确,x 将是 2**−53+2**−105,因为将此 x 添加到 1 会导致舍入到下一个可表示的值 1+2**−52 .
猜你喜欢
  • 1970-01-01
  • 2017-02-15
  • 2011-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多