【问题标题】:whats the biggest number that is smaller than FLT_EPSILON?小于 FLT_EPSILON 的最大数字是多少?
【发布时间】:2012-01-31 01:11:43
【问题描述】:

在 C 中使用 float.h 我想知道如何找到最大的数字,如果我加 1,答案将保持 1。

即 1 + x = 1 如何找到 x?

【问题讨论】:

  • @KerrekSB EPS/2 可能满足条件,但不一定是最大的

标签: c floating-point floating-accuracy


【解决方案1】:

如果你想要“小于 FLT_EPSILON 的最大数”:

x = nextafterf(FLT_EPSILON, 0)

如果你想要最大的数字x,比如1.0f + x == 1.0f,那么答案取决于舍入模式,但在默认舍入模式下,它只是FLT_EPSILON/2

然而,事情并不是那么简单。由于在 tie 上对 even 邻居进行舍入到最近舍入的方式,您有 1.0f + FLT_EPSILON/2 == 1.0f,但是:

(1.0f+FLT_EPSILON) + FLT_EPSILON/2 != (1.0f+FLT_EPSILON)

因此,您可能希望使用稍小的x 值:

x = nextafterf(FLT_EPSILON/2, 0)

这将确保y+x == y 用于任何y >= 1.0

【讨论】:

  • 该题使用了FLT_EPSILON的非正式和错误定义作为可以添加到1.0f以获得1.0f以外的值的最小浮点数。正确的定义是1.0f的后继者和1.0f的区别。对于这个正确的定义,您的候选人nextafterf(FLT_EPSILON, 0) 不具有 1.0f + 候选人 == 1.0f 的属性。这不是你的错,而是问题所在。
  • 是的,我现在看到问题是不一致的。我回答了主题行,但这并没有给出邮件正文的正确答案。
【解决方案2】:

这取决于舍入模式。这是一个简单的例子。假设我们的精度是 4 位,并且我们有某种 IEEE754 表示。所以值 1 存储为 1.0000 × 20。下一个更大的数字是 1.0001 × 20,机器 epsilon ε 定义为两者之差,即 0.0001 × 20 = 1.0000 × 2−4。现在:

  • ε / 2 = 1.0000 × 2-5 = 0.00001,并且

  • ε / 4 = 1.0000 × 2−6 = 0.000001。

当您将两者之一加到 1 时,数字首先被重写为 2 的幂0,并在分隔符后四舍五入为 4 位。 ε / 4 的剩余尾数肯定是 0.0000,而 ε / 2 的剩余尾数是 0.0000 或 0.0001,具体取决于您是向上还是向下舍入。

只要有效的结果尾数为 0.0000,就可以将数字加 1,而不改变其值。

(对于单精度、双精度和扩展双精度浮点数,实际精度分别为 23+1、52+1 和 64。)

【讨论】:

    猜你喜欢
    • 2013-01-09
    • 1970-01-01
    • 2013-02-26
    • 2012-06-30
    • 2011-03-13
    • 1970-01-01
    • 2018-09-07
    • 1970-01-01
    • 2011-03-16
    相关资源
    最近更新 更多