1

ウィキペディアで、4倍精度を実装するには、ビットに関して正確に同じ精度でなくても、倍精度演算を使用することであることがわかりました: https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format

この場合、2 つの double を使用して値を格納します。そのため、結果を計算するために 2 つの操作を行います。結果の double ごとに 1 つです。

この場合、各 double に丸め誤差が発生する可能性がありますか、それともこれを回避するメカニズムですか?

4

1 に答える 1

7

「この場合、2 つの double を使用して値を格納します。そのため、一度に 2 つの操作を行う必要があります。」</p>

これは double-double 算術がどのように機能するかではありません。実装される実際の演算、融合乗算加算演算の可用性、一方のオペランドが他方よりも大きいという仮定に応じて、1 つの double-double 演算が 6 ~ 20 回の double 演算で実装されることを期待する必要があります。 </p>

たとえば、CRlibmから取得した、FMA 命令が使用できない場合の double-double 乗算の実装の 1 つを次に示します。

#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 を 2 つの半分に正確に分割するためのものです。これにより、各側の半分を反対側の半分で乗算し、結果を a として正確に取得できdoubleます。計算u1*v1u1*v2、 … はまさにそれを行います。

mhとで取得された値mlは重複する可能性があるため、最後の 3 つの演算は、結果を 2 つの浮動小数点数の合計に再正規化するためにあります。

この場合、各 double に丸め誤差が発生する可能性がありますか、それともこれを回避するメカニズムですか?

コメントが言うように:

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

これらの結果を達成するために使用されるすべてのメカニズムについては、Handbook of Floating-Point Arithmetic を参照してください。

于 2015-07-27T08:09:43.333 に答える