float128和双倍算术

时间:2015-07-27 07:38:01

标签: c++ floating-point ieee-754

我在维基百科中看到,实现四倍精度的方法是使用双倍算术,即使它在位数方面的精度不完全相同:https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format

在这种情况下,我们使用两个double来存储值。因此,我们进行了两次运算来计算结果,每次运算得到两次结果。

在这种情况下,我们可以在每个double上有舍入错误,或者它们是一种避免这种情况的机制吗?

1 个答案:

答案 0 :(得分:5)

  

“在这种情况下,我们使用两个double来存储值。所以我们每次都需要做两次操作。“

这不是双重算术的工作原理。你应该期望在6到20次双重操作的任何地方实现一个双重操作,具体取决于实现的实际操作,融合乘法 - 加法运算的可用性,假设一个操作数大于另一个,...

例如,这是一个双倍乘法的实现,当FMA指令不可用时,取自CRlibm

#define Mul22(zh,zl,xh,xl,yh,yl)                      \
{                                                     \
double mh, ml;                                        \
                              \
  const double c = 134217729.;                \
  double up, u1, u2, vp, v1, v2;              \
                              \
  up = (xh)*c;        vp = (yh)*c;            \
  u1 = ((xh)-up)+up;  v1 = ((yh)-vp)+vp;          \
  u2 = (xh)-u1;       v2 = (yh)-v1;                   \
                              \
  mh = (xh)*(yh);                     \
  ml = (((u1*v1-mh)+(u1*v2))+(u2*v1))+(u2*v2);        \
                              \
  ml += (xh)*(yl) + (xl)*(yh);                \
  *zh = mh+ml;                        \
  *zl = mh - (*zh) + ml;                              \
}

前8个操作单独用于将每个双精度从操作数分成两半,这样每侧的一半可以从另一侧乘以一半,结果与double完全相同。计算u1*v1u1*v2,......就是这么做的。

mhml中获得的值可以重叠,因此最后3个操作可以将结果重新规范化为两个浮点数的总和。

  

在这种情况下,我们可以在每个double上有舍入错误,或者它们是一种避免这种情况的机制吗?

正如评论所说:

/*
 * computes double-double multiplication: zh+zl = (xh+xl) *  (yh+yl)
 * relative error is smaller than 2^-102
 */

您可以在Handbook of Floating-Point Arithmetic中找到用于实现这些结果的所有机制。