`nextafter` 和 `nexttoward`:为什么是这个特定的界面?

AnT*_*AnT 5 c floating-point standard-library

这种特殊的nextafter(和nexttoward函数接口背后的原因究竟是什么?我们指定的方向通过指定我们想要移动的价值走向

乍一看,这个想法背后似乎隐藏着一些不明显的东西。在我(天真)看来,此类函数的首选将类似于一对单参数函数nextafter(a)/ nextbefore(a)。下一个选择将是一个双参数函数nextafter(a, dir),其中dir明确指定方向(-1+1,一些标准枚举等)。

而是我们必须指定一个,我们希望移动走向。因此有许多问题

  1. (一个模糊的)。可能有一些聪明的想法或惯用的模式非常有价值,以至于影响了这些标准功能中的接口选择。在那儿?

  2. 如果决定盲目地使用-DBL_MAX+DBL_MAX作为nextafter分别指定负方向和正方向的第二个参数会怎样。这样做有什么陷阱吗?

  3. (2 的改进)。如果我知道肯定b是[轻微]大于a,没有任何理由,更喜欢nextafter(a, b)nextafter(a, DBL_MAX)?例如,nextafter(a, b)版本是否有更好的性能?

  4. nextafter通常一个沉重的操作?我知道它是依赖于实现的。但是,再次假设一个基于 IEEE 754 表示的实现,找到相邻的浮点值是否相当“困难”?

ric*_*ici 5

对于 IEEE-754 二进制浮点表示,如果 的两个参数nextafter都是有限的并且两个参数不相等,则可以通过在重新解释为无符号整数的数字表示中加一或减一来计算结果 [注1]。(轻微的)复杂性是由于正确处理不满足这些先决条件的极端情况而产生的,但总的来说,您会发现它非常快。

除了 NaN 之外,第二个参数唯一重要的是它是否大于、小于或等于第一个参数。

该界面基本上为极端情况结果提供了额外的清晰度,但有时也很有用。nextafter(x, 0)特别是,无论符号如何都会截断的用法通常很方便。您还可以利用nextafter(x, x);x结果限制在任意值的事实。

nextafter和之间的区别nexttowards在于后者允许您使用更大的动态范围long double;同样,这有助于解决某些极端情况。


  1. 严格来说,如果第一个参数是某个符号的零,而另一个参数是相反符号的有效非零数,则该参数需要在递增之前翻转其符号位。但将其添加到列表中似乎有太多法律术语,而且它仍然不是一个复杂的转换。