【发布时间】:2023-11-19 22:14:01
【问题描述】:
浮点边界的区间可用于过度近似实数集,只要任何结果区间的上限是向上舍入计算的,而下限是向下舍入计算的。
一个推荐的技巧是实际计算下界的否定。这允许 FPU 始终保持向上舍入(例如,“Handbook of Floating-Point Arithmetic”,2.9.2)。
这适用于加法和乘法。另一方面,平方根运算在加法和乘法方面是不对称的。
我突然想到,为了计算 sqrtRD,对于下限,以下习语尽管很复杂,但在具有 IEEE 754 双精度和 @ 的普通平台上可能会更快987654321@定义为0比改变舍入模式两次:
#include <fenv.h>
#include <math.h>
#pragma STDC FENV_ACCESS ON
…
/* assumes round-upwards */
double sqrt_rd(double l) {
feclearexcept(FE_INEXACT);
double candidate = sqrt(l);
if (fetestexcept(FE_INEXACT))
return nextafter(candidate, 0);
return candidate;
}
我想知道这是否更好,以及它是否是最快的。作为一种可能的替代方案,但仍不一定是最快的,在我看来 FMARU(candidate, Candidate, -l) 可能并不总是准确的(因为有向舍入),但可能是在 0 左右足够准确,以便以下工作:
/* assumes round-upwards */
double sqrt_rd(double l) {
double candidate = sqrt(l);
if (fma(candidate, candidate, -l) != 0.0)
return nextafter(candidate, 0);
return candidate;
}
还有什么其他廉价的方法可以检测到sqrt 是不准确的?
在设置为向上舍入的现代 FPU 上,哪种浮点运算组合可以最快地计算 sqrt_rd?
【问题讨论】:
-
我怀疑这取决于实现和实际环境。
-
@Olaf 我已经更新了这个问题,其中包含这是针对具有 IEEE 754 双精度和 FLT_EVAL_METHOD=0 的平台的信息。
-
这没有多大帮助。 “实现”是编译器,“环境”是目标平台/架构。展示极端情况:可能没有可用的 FPU,或者整个函数可能导致单个 FPU 指令。
-
@Olaf 任何喜欢对其解决方案进行基准测试的人都可以使用 Haswell 处理器和 GCC 5.3.0。我希望有一些对于如此广泛的平台来说显然是一种收益的东西,它不需要进行基准测试,比如最初的“将 mult_rd(x, y) 计算为 -mult_ru(-x, y)”技巧。
标签: c floating-point c99 ieee-754