【发布时间】:2012-01-31 01:11:43
【问题描述】:
在 C 中使用 float.h 我想知道如何找到最大的数字,如果我加 1,答案将保持 1。
即 1 + x = 1 如何找到 x?
【问题讨论】:
-
@KerrekSB EPS/2 可能满足条件,但不一定是最大的
标签: c floating-point floating-accuracy
在 C 中使用 float.h 我想知道如何找到最大的数字,如果我加 1,答案将保持 1。
即 1 + x = 1 如何找到 x?
【问题讨论】:
标签: c floating-point floating-accuracy
如果你想要“小于 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。
【讨论】:
nextafterf(FLT_EPSILON, 0) 不具有 1.0f + 候选人 == 1.0f 的属性。这不是你的错,而是问题所在。
这取决于舍入模式。这是一个简单的例子。假设我们的精度是 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。)
【讨论】: