在RU模式下用FPU计算RD(sqrt(x))

只要任何结果区间的上限是在上舍入时计算的,而下舍入在下舍入时,浮点边界的区间就可以用来过度逼近集合的实数。

一个推荐的技巧是实际计算下界的否定。 这可以使FPU始终保持在圆形上(例如,“浮点运算手册”,2.9.2)。

这适用于加法和乘法。 另一方面,平方根运算在加法和乘法方面不是对称的。

对我来说,为了计算sqrtRD,对于下限,尽管存在其复杂性,但下面的习惯用法在IEEE 754双精度和FLT_EVAL_METHOD定义为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(候选人,候选人-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的最快计算向上舍入?


我认为你应该可以使用:

/* assumes round-upwards */
double sqrt_rd(double l) { 
  double u = sqrt(l);
  double w = u*u;
  if (w != l)
    return nextafter(u, 0);
  return u;
}

这里的理由是如果u是不精确的,那么这将是比√严格地l ,这反过来又意味着, w > = u 2> l (因为w在RU模式也计算)。 如果u是确切的,那么w也是如此(因为我们知道它必须表示为双精度)。


fma以无限精度计算结果,然后应用舍入模式。

如果你的候选人太大,那么无限精确的结果大于0,并且因为你正在四舍五入,所以它会被取整。 即使它只比零大一点点。 为了验证这一点,首先尝试l = 1 + 2eps,其中(1 + eps)= sqrt(1 + 2eps + eps ^ 2)只是一点点太大; 然后缩小4的负幂,使eps ^ 2远远超出非规格化数的分辨率,并检查。

链接地址: http://www.djcxy.com/p/85613.html

上一篇: Computing RD(sqrt(x)) with a FPU in RU mode

下一篇: What is the worst case accuracy for dot product?