xeij/EFPBox.java (2/3)
1 2 3
        if (false) {
          if ((xd << 1 + xe | xc) != 0L) {  //端数がある
            epbFpsr |= EPB_FPSR_X2;  //不正確な結果
            epbExceptionOperandExponent = xf | 0x3fff + xe << 16;
            epbExceptionOperandMantissa = xd;
          }
        }
        return xf >= 0 ? (int) (xd >>> ~xe) : -(int) (xd >>> ~xe);
      }
      //2^7<=|x|
      if (xf >= 0) {  //2^7<=x
        epbFpsr |= EPB_FPSR_OE;
        epbExceptionOperandExponent = 0x3fff + xe << 16;
        epbExceptionOperandMantissa = xd;
        return 0x0000007f;
      }
      //x<=-2^7
      if (xe != 7 || xd != MSB || xc != 0L) {  //x!=-2^7
        epbFpsr |= EPB_FPSR_OE;
        epbExceptionOperandExponent = M | 0x3fff + xe << 16;
        epbExceptionOperandMantissa = this.dvl;
      }
      return 0xffffff80;
    }  //efp.getb()
    public int getb (int roundingMode) {
      return (roundingMode == EPB_MODE_RN ? new EFP ().inner ().rint (this).outer ().getb () :
              roundingMode == EPB_MODE_RM ? new EFP ().inner ().floor (this).outer ().getb () :
              roundingMode == EPB_MODE_RP ? new EFP ().inner ().ceil (this).outer ().getb () :
              new EFP ().inner ().trunc (this).outer ().getb ());
    }  //efp.getb(int)

    //------------------------------------------------------------------------
    //d = x.getd ()
    //d = x.getd (roundingMode)
    //b = x.getd01 (b, a)
    //b = x.getd01 (b, a, roundingMode)
    //ib = x.getd01 (ib, ia)
    //ib = x.getd01 (ib, ia, roundingMode)
    //l = x.getd01 ()
    //l = x.getd01 (roundingMode)
    //  double値
    //
    //    0x7fffffffffffffffL  Non-Signaling NaN
    //    0x7ff7ffffffffffffL  Signaling NaN
    //    0x7ff0000000000000L  +Inf
    //    0x7fefffffffffffffL  2^1024-2^971    = 1.7976931348623157081452742373170435680 E308   正規化数の最大値
    //    0x3ff0000000000000L  2^0             = 1
    //    0x0010000000000000L  2^-1022         = 2.2250738585072013830902327173324040642 E-308  正規化数の最小値
    //    0x000fffffffffffffL  2^-1022-2^-1074 = 2.2250738585072008890245868760858598877 E-308  非正規化数の最大値
    //    0x0000000000000001L  2^-1074         = 4.9406564584124654417656879286822137237 E-324  非正規化数の最小値
    //    0x0000000000000000L  +0
    //    NaNの符号はDon't Care、出力は0
    //    Non-Signaling NaNの小数部の先頭は1
    //    Signaling NaNの小数部の先頭は0
    //      Signaling NaNが返ることはない
    //    NaNの小数部の先頭以外はNon-Zero、出力はすべて1
    //    ±Infの小数部はすべて0
    //
    //    for (long l : new long[] {
    //      0x7ff0000000000000L,
    //      0x7fefffffffffffffL,
    //      0x3ff0000000000000L,
    //      0x0010000000000000L,
    //      0x000fffffffffffffL,
    //      0x0000000000000001L,
    //      0x0000000000000000L,
    //    }) {
    //      System.out.printf ("      //  0x%016x  %.17g\n", l, Double.longBitsToDouble (l));
    //    }
    //    0x7ff0000000000000  Infinity
    //    0x7fefffffffffffff  1.7976931348623157e+308
    //    0x3ff0000000000000  1.0000000000000000
    //    0x0010000000000000  2.2250738585072014e-308
    //    0x000fffffffffffff  2.2250738585072010e-308
    //    0x0000000000000001  4.9000000000000000e-324  不正確なのではなくて非正規化数の有効桁数が調整されている
    //    0x0000000000000000  0.0000000000000000
    //
    //  丸めモードを省略したときは最も近い値に丸める(RN)
    //
    public final double getd () {
      return getd (EPB_MODE_RN);
    }  //efp.getd()
    public final double getd (int roundingMode) {
      return Double.longBitsToDouble (getd01 (roundingMode));
    }  //efp.getd(int)
    public final byte[] getd01 (byte[] b, int a) {
      return getd01 (b, a, EPB_MODE_RN);
    }  //efp.getd01(byte[],int)
    public final byte[] getd01 (byte[] b, int a, int roundingMode) {
      long l = getd01 (roundingMode);
      b[a] = (byte) (l >> 56);
      b[a + 1] = (byte) (l >> 48);
      b[a + 2] = (byte) (l >> 40);
      b[a + 3] = (byte) (l >> 32);
      b[a + 4] = (byte) (l >> 24);
      b[a + 5] = (byte) (l >> 16);
      b[a + 6] = (byte) (l >> 8);
      b[a + 7] = (byte) l;
      return b;
    }  //efp.getd01(byte[],int,int)
    public final int[] getd01 (int[] ib, int ia) {
      return getd01 (ib, ia, EPB_MODE_RN);
    }  //efp.getd01(int[],int)
    public final int[] getd01 (int[] ib, int ia, int roundingMode) {
      long l = getd01 (roundingMode);
      ib[ia] = (int) (l >> 32);
      ib[ia + 1] = (int) l;
      return ib;
    }  //efp.getd01(int[],int,int)
    public final long getd01 () {
      return getd01 (EPB_MODE_RN);
    }  //efp.getd01()
    public final long getd01 (int roundingMode) {
      int xf = this.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        return (xf << 1 < 0 ? 0 <= xf ? 0x0000000000000000L : 0x8000000000000000L :  //±0
                xf << 2 < 0 ? 0 <= xf ? 0x7ff0000000000000L : 0xfff0000000000000L :  //±Inf
                EFP_FPCP_NAN ? 0x7fffffffffffffffL : 0x7ff8000000000000L);  //NaN
      }
      //±0,±Inf,NaN以外
      int xe = this.epp;  //正規化数は-1022<=xe<=1023、非正規化数は-1075<=xe<=-1023
      long xd = this.dvl;
      long xc = this.cvl;
      if (xe < -1075) {  //指数部が小さすぎる。非正規化数の最小値は2^-1074だが丸めで繰り上がる場合があるので一旦2^-1075まで受け入れる
        epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
        epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
        epbExceptionOperandMantissa = xd;
        return (0 <= xf ?
                roundingMode == EPB_MODE_RP ? 0x0000000000000001L : 0x0000000000000000L :  //RPのとき+eps,RN,RZ,RMのとき+0
                roundingMode == EPB_MODE_RM ? 0x8000000000000001L : 0x8000000000000000L);  //RMのとき-eps,RN,RZ,RPのとき-0
      }
      if (1023 < xe) {  //指数部が大きすぎる
        if (true) {
          epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
          if ((xd << 53 | xc) != 0L) {  //端数が0ではない
            epbFpsr |= EPB_FPSR_X2;  //不正確な結果
          }
        } else {
          epbFpsr |= EPB_FPSR_OF | EPB_FPSR_X2;  //オーバーフロー、不正確な結果
        }
        epbExceptionOperandExponent = xf | 0x3fff - 0x6000 + xe << 16;
        epbExceptionOperandMantissa = xd;
        return (0 <= xf ?
                roundingMode == EPB_MODE_RZ || roundingMode == EPB_MODE_RM ? 0x7fefffffffffffffL : 0x7ff0000000000000L :  //RZ,RMのとき+max,RN,RPのとき+Inf
                roundingMode == EPB_MODE_RZ || roundingMode == EPB_MODE_RP ? 0xffefffffffffffffL : 0xfff0000000000000L);  //RZ,RPのとき-max,RN,RMのとき-Inf
      }
      long xb = 0L;
      int o = xe <= -1023 ? 11 + -1022 - xe : 11;  //右にずらすbit数。正規化数は11、非正規化数は11+1<=o<=11+53
      if (o < 64) {
        xb = xc << -o;
        xc = xd << -o | xc >>> o;
        xd >>>= o;
      } else {
        xb = xc;
        xc = xd;
        xd = 0L;
      }
      if ((xc | xb) != 0L) {  //端数が0ではない
        epbFpsr |= EPB_FPSR_X2;  //不正確な結果
        if (roundingMode == EPB_MODE_RN && xc < 0L && (xd << 63 | xc << 1 | xb) != 0L ||  //RNでguard bitが1かつLSBまたはguard bit以外の端数が0ではないまたは
            roundingMode == EPB_MODE_RM && xf < 0 ||  //端数が0ではなくてRMで-または
            roundingMode == EPB_MODE_RP && 0 <= xf) {  //端数が0ではなくてRPで+のとき
          xd++;  //繰り上げる
          if (xd >>> 53 != 0L) {  //繰り上がって溢れたとき
            xd = 1L << 52;
            xe++;  //指数部をインクリメントする。ここでxe=1024になる場合がある
            if (1023 < xe) {  //指数部が大きすぎる
              epbFpsr |= EPB_FPSR_OF | EPB_FPSR_X2;  //オーバーフロー、不正確な結果
              epbExceptionOperandExponent = xf | 0x3fff - 0x6000 + xe << 16;
              epbExceptionOperandMantissa = xd;
              return (0 <= xf ?
                      roundingMode == EPB_MODE_RZ || roundingMode == EPB_MODE_RM ? 0x7fefffffffffffffL : 0x7ff0000000000000L :  //RZ,RMのとき+max,RN,RPのとき+Inf
                      roundingMode == EPB_MODE_RZ || roundingMode == EPB_MODE_RP ? 0xffefffffffffffffL : 0xfff0000000000000L);  //RZ,RPのとき-max,RN,RMのとき-Inf
            }  //if 指数部が大きすぎる
          } else if (11 < o) {  //非正規化数のとき
            if (xd << o - 1 < 0L) {  //1bit増えたとき
              xe++;  //指数部をインクリメントする
/* getd01 */
              if (xe == -1022) {  //非正規化数が繰り上がって正規化数になったとき
                //xd = 1L << 52;
                epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
                epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
                epbExceptionOperandMantissa = xd;
              }
/**/
            }
          }
        }
        //RZ toward zeroのときは端数を切り捨てるだけなので何もしなくてよい
        if (xe <= -1023) {  //非正規化数
          epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
          epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
          epbExceptionOperandMantissa = xd;
          if (xd == 0L) {  //非正規化数でxe==-1075だったとき、先頭の1がxcにあって丸めで繰り上がらなかった
            return (0 <= xf ?
                    roundingMode == EPB_MODE_RP ? 0x0000000000000001L : 0x0000000000000000L :  //RPのとき+eps,RN,RZ,RMのとき+0
                    roundingMode == EPB_MODE_RM ? 0x8000000000000001L : 0x8000000000000000L);  //RMのとき-eps,RN,RZ,RPのとき-0
          }
        }  //if 非正規化数
      } else {  //端数が0
        if (xe <= -1023) {  //非正規化数
          epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
          epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
          epbExceptionOperandMantissa = xd;
          if (xd == 0L) {  //非正規化数でxe==-1075だったとき、先頭の1がxcにあって丸めで繰り上がらなかった
            return (0 <= xf ?
                    roundingMode == EPB_MODE_RP ? 0x0000000000000001L : 0x0000000000000000L :  //RPのとき+eps,RN,RZ,RMのとき+0
                    roundingMode == EPB_MODE_RM ? 0x8000000000000001L : 0x8000000000000000L);  //RMのとき-eps,RN,RZ,RPのとき-0
          }
        }  //if 非正規化数
      }  //if 端数が0ではない/端数が0
      return ((long) (xf | Math.max (0, xe + 1023) << 52 - 32) << 32 |  //符号と指数部
              xd & ((1L << 52) - 1L));  //仮数部。正規化数のときは先頭の1を取り除く
    }  //efp.getd01(int)

    //------------------------------------------------------------------------
    //x = x.getexp ()
    //y = y.getexp (x)
    //  指数部
    //
    //  getexp(±0)=±0, getexp(±Inf)=NaN, getexp(NaN)=NaN
    //
    public final EFP getexp () {
      return this.getexp (this);
    }  //efp.getexp()
    public final EFP getexp (EFP x) {
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        if (xf << 2 < 0) {  //±Inf
          epbFpsr |= EPB_FPSR_OE;
          epbExceptionOperandExponent = xf & M | 0x7fff << 16;
          epbExceptionOperandMantissa = 0x0000000000000000L;
          this.flg = N;  //getexp(±Inf)=NaN
        } else {  //±0,NaN
          this.flg = xf;  //getexp(±0)=±0, getexp(NaN)=NaN
        }
        return this;
      }
      return this.seti (x.epp);  //指数部
    }  //efp.getexp(EFP)

    //------------------------------------------------------------------------
    //f = x.getf ()
    //f = x.getf (roundingMode)
    //b = x.getf0 (b, a)
    //b = x.getf0 (b, a, roundingMode)
    //ib = x.getf0 (ib, a)
    //ib = x.getf0 (ib, a, roundingMode)
    //i = x.getf0 ()
    //i = x.getf0 (roundingMode)
    //  float値
    //
    //    0x7fffffff  Non-Signaling NaN
    //    0x7fbfffff  Signaling NaN
    //    0x7f800000  +Inf
    //    0x7f7fffff  2^128-2^104   = 3.4028234663852885981170418348451692544 E38   正規化数の最大値
    //    0x3f800000  2^0           = 1
    //    0x00800000  2^-126        = 1.1754943508222875079687365372222456778 E-38  正規化数の最小値
    //    0x007fffff  2^-126-2^-149 = 1.1754942106924410754870294448492873488 E-38  非正規化数の最大値
    //    0x00000001  2^-149        = 1.4012984643248170709237295832899161313 E-45  非正規化数の最小値
    //    0x00000000  +0
    //    NaNの符号はDon't Care、出力は0
    //    Non-Signaling NaNの小数部の先頭は1
    //    Signaling NaNの小数部の先頭は0
    //      Signaling NaNが返ることはない
    //    NaNの小数部の先頭以外はNon-Zero、出力はすべて1
    //    ±Infの小数部はすべて0
    //
    //    for (int i : new int[] {
    //      0x7f800000,
    //      0x7f7fffff,
    //      0x3f800000,
    //      0x00800000,
    //      0x007fffff,
    //      0x00000001,
    //      0x00000000,
    //    }) {
    //      System.out.printf ("      //  0x%08x  %.17g\n", i, Float.intBitsToFloat (i));
    //    }
    //    0x7f800000  Infinity
    //    0x7f7fffff  3.4028234663852886e+38
    //    0x3f800000  1.0000000000000000
    //    0x00800000  1.1754943508222875e-38
    //    0x007fffff  1.1754942106924411e-38
    //    0x00000001  1.4012984643248170e-45  doubleでは正規化数なので有効桁数は17桁
    //    0x00000000  0.0000000000000000
    //
    //  丸めモードを省略したときは最も近い値に丸める(RN)
    //
    public final float getf () {
      return getf (EPB_MODE_RN);
    }  //efp.getf()
    public final float getf (int roundingMode) {
      return Float.intBitsToFloat (getf0 (roundingMode));
    }  //efp.getf(int)
    public final byte[] getf0 (byte[] b, int a) {
      return getf0 (b, a, EPB_MODE_RN);
    }  //efp.getf0(byte[],int)
    public final byte[] getf0 (byte[] b, int a, int roundingMode) {
      int i = getf0 (roundingMode);
      b[a] = (byte) (i >> 24);
      b[a + 1] = (byte) (i >> 16);
      b[a + 2] = (byte) (i >>  8);
      b[a + 3] = (byte) i;
      return b;
    }  //efp.getf0(byte[],int,int)
    public final int[] getf0 (int[] ib, int ia) {
      return getf0 (ib, ia, EPB_MODE_RN);
    }  //efp.getf0(int[],int)
    public final int[] getf0 (int[] ib, int ia, int roundingMode) {
      ib[ia] = getf0 (roundingMode);
      return ib;
    }  //efp.getf0(int[],int,int)
    public final int getf0 () {
      return getf0 (EPB_MODE_RN);
    }  //efp.getf0()
    public final int getf0 (int roundingMode) {
      int xf = this.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        return (xf << 1 < 0 ? xf & M :  //±0
                xf << 2 < 0 ? (xf & M) | 0x7f800000 :  //±Inf
                EFP_FPCP_NAN ? 0x7fffffff : 0x7fc00000);  //NaN
      }
      //±0,±Inf,NaN以外
      int xe = this.epp;  //正規化数は-126<=xe<=127、非正規化数は-149<=xe<=-127
      long xd = this.dvl;
      long xc = this.cvl;
      if (xe < -150) {  //指数部が小さすぎる。非正規化数の最小値は2^-149だが丸めで繰り上がる場合があるので一旦2^-150まで受け入れる
        epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
        epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
        epbExceptionOperandMantissa = xd;
        return (0 <= xf ?
                roundingMode == EPB_MODE_RP ? 0x00000001 : 0x00000000 :  //RPのとき+eps,RN,RZ,RMのとき+0
                roundingMode == EPB_MODE_RM ? 0x80000001 : 0x80000000);  //RMのとき-eps,RN,RZ,RPのとき-0
      }
      if (127 < xe) {  //指数部が大きすぎる
        if (true) {
          epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
          if ((xd << 24 | xc) != 0L) {  //端数が0ではない
            epbFpsr |= EPB_FPSR_X2;  //不正確な結果
          }
        } else {
          epbFpsr |= EPB_FPSR_OF | EPB_FPSR_X2;  //オーバーフロー、不正確な結果
        }
        epbExceptionOperandExponent = xf | 0x3fff - 0x6000 + xe << 16;
        epbExceptionOperandMantissa = xd;
        return (0 <= xf ?
                roundingMode == EPB_MODE_RZ || roundingMode == EPB_MODE_RM ? 0x7f7fffff : 0x7f800000 :  //RZ,RMのとき+max,RN,RPのとき+Inf
                roundingMode == EPB_MODE_RZ || roundingMode == EPB_MODE_RP ? 0xff7fffff : 0xff800000);  //RZ,RPのとき-max,RN,RMのとき-Inf
      }
      long xb = 0L;
      int o = xe <= -127 ? 40 + -126 - xe : 40;  //右にずらすbit数。正規化数は40、非正規化数は40+1<=o<=40+24
      if (o < 64) {
        xb = xc << -o;
        xc = xd << -o | xc >>> o;
        xd >>>= o;
      } else {
        xb = xc;
        xc = xd;
        xd = 0L;
      }
      if ((xc | xb) != 0L) {  //端数が0ではない
        epbFpsr |= EPB_FPSR_X2;  //不正確な結果
        if (roundingMode == EPB_MODE_RN && xc < 0L && (xd << -1 | xc << 1 | xb) != 0L ||  //RNでguard bitが1かつLSBまたはguard bit以外の端数が0ではないまたは
            roundingMode == EPB_MODE_RM && xf < 0 ||  //端数が0ではなくてRMで-または
            roundingMode == EPB_MODE_RP && 0 <= xf) {  //端数が0ではなくてRPで+のとき
          xd++;  //繰り上げる
          if (xd >>> 24 != 0L) {  //繰り上がって溢れたとき
            xd = 1L << 23;
            xe++;  //指数部をインクリメントする。ここでxe=128になる場合がある
            if (127 < xe) {  //指数部が大きすぎる
              epbFpsr |= EPB_FPSR_OF | EPB_FPSR_X2;  //オーバーフロー、不正確な結果
              epbExceptionOperandExponent = xf | 0x3fff - 0x6000 + xe << 16;
              epbExceptionOperandMantissa = xd;
              return (0 <= xf ?
                      roundingMode == EPB_MODE_RZ || roundingMode == EPB_MODE_RM ? 0x7f7fffff : 0x7f800000 :  //RZ,RMのとき+max,RN,RPのとき+Inf
                      roundingMode == EPB_MODE_RZ || roundingMode == EPB_MODE_RP ? 0xff7fffff : 0xff800000);  //RZ,RPのとき-max,RN,RMのとき-Inf
            }
          } else if (40 < o) {  //非正規化数のとき
            if (xd << o - 1 < 0L) {  //1bit増えたとき
              xe++;  //指数部をインクリメントする
/* getf0 */
              if (xe == -126) {  //非正規化数が繰り上がって正規化数になったとき
                //xd = 1L << 23;
                epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
                epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
                epbExceptionOperandMantissa = xd;
              }
/**/
            }
          }
        }
        //RZ toward zeroのときは端数を切り捨てるだけなので何もしなくてよい
        if (xe <= -127) {  //非正規化数
          epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
          epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
          epbExceptionOperandMantissa = xd;
          if (xd == 0L) {  //非正規化数でxe==-150だったとき、先頭の1がxcにあって丸めで繰り上がらなかった
            return (0 <= xf ?
                    roundingMode == EPB_MODE_RP ? 0x00000001 : 0x00000000 :  //RPのとき+eps,RN,RZ,RMのとき+0
                    roundingMode == EPB_MODE_RM ? 0x80000001 : 0x80000000);  //RMのとき-eps,RN,RZ,RPのとき-0
          }
        }  //if 非正規化数
      } else {  //端数が0
        if (xe <= -127) {  //非正規化数
          epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
          epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
          epbExceptionOperandMantissa = xd;
          if (xd == 0L) {  //非正規化数でxe==-150だったとき、先頭の1がxcにあって丸めで繰り上がらなかった
            return (0 <= xf ?
                    roundingMode == EPB_MODE_RP ? 0x00000001 : 0x00000000 :  //RPのとき+eps,RN,RZ,RMのとき+0
                    roundingMode == EPB_MODE_RM ? 0x80000001 : 0x80000000);  //RMのとき-eps,RN,RZ,RPのとき-0
          }
        }  //if 非正規化数
      }  //if 端数が0ではない/端数が0
      return (xf | Math.max (0, xe + 127) << 23 |  //符号と指数部
              (int) xd & ((1 << 23) - 1));  //仮数部。正規化数のときは先頭の1を取り除く
    }  //efp.getf0(int)

    //------------------------------------------------------------------------
    //i = x.geti ()
    //i = x.geti (roundingMode)
    //  int値
    //
    //  丸めモードを省略したときは小数点以下を切り捨てる(RZ)
    //  2^31-1よりも大きい数は2^31-1に、-2^31よりも小さい数は-2^31に変換する(飽和変換)
    //  NaNは-1に変換する
    //
    public int geti () {
      int xf = this.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        if (xf << 1 < 0) {  //±0
          return 0;
        } else if (xf << 2 < 0) {  //±Inf
          epbFpsr |= EPB_FPSR_OE;
          epbExceptionOperandExponent = xf & M | 0x7fff << 16;
          epbExceptionOperandMantissa = 0x0000000000000000L;
          return xf >> 31 ^ 0x7fffffff;  //+Infは0x7fffffff,-Infは0x80000000
        } else {  //NaN
          epbFpsr |= EPB_FPSR_OE | EPB_FPSR_AV;
          epbExceptionOperandExponent = 0x7fff << 16;
          epbExceptionOperandMantissa = 0xffffffffffffffffL;
          return -1;  //NaNは-1
        }
      }
      //±0,±Inf,NaN以外
      int xe = this.epp;
      long xd = this.dvl;
      long xc = this.cvl;
      if (xe < 0) {  //0<|x|<1
        if (false) {
          epbFpsr |= EPB_FPSR_X2;  //不正確な結果
          epbExceptionOperandExponent = xf | 0x3fff + xe << 16;
          epbExceptionOperandMantissa = xd;
        }
        return 0;
      }
      //1<=|x|
      if (xe < 31) {  //1<=|x|<2^31
        if (false) {
          if ((xd << 1 + xe | xc) != 0L) {  //端数がある
            epbFpsr |= EPB_FPSR_X2;  //不正確な結果
            epbExceptionOperandExponent = xf | 0x3fff + xe << 16;
            epbExceptionOperandMantissa = xd;
          }
        }
        return xf >= 0 ? (int) (xd >>> ~xe) : -(int) (xd >>> ~xe);
      }
      //2^31<=|x|
      if (xf >= 0) {  //2^31<=x
        epbFpsr |= EPB_FPSR_OE;
        epbExceptionOperandExponent = 0x3fff + xe << 16;
        epbExceptionOperandMantissa = xd;
        return 0x7fffffff;
      }
      //x<=-2^31
      if (xe != 31 || xd != MSB || xc != 0L) {  //x!=-2^31
        epbFpsr |= EPB_FPSR_OE;
        epbExceptionOperandExponent = M | 0x3fff + xe << 16;
        epbExceptionOperandMantissa = this.dvl;
      }
      return 0x80000000;
    }  //efp.geti()
    public int geti (int roundingMode) {
      return (roundingMode == EPB_MODE_RN ? new EFP ().inner ().rint (this).outer ().geti () :
              roundingMode == EPB_MODE_RM ? new EFP ().inner ().floor (this).outer ().geti () :
              roundingMode == EPB_MODE_RP ? new EFP ().inner ().ceil (this).outer ().geti () :
              new EFP ().inner ().trunc (this).outer ().geti ());
    }  //efp.geti(int)

    //------------------------------------------------------------------------
    //i = x.geti32 ()
    //  x&0xffffffff
    //  整数部の下位32bit
    //
    public int geti32 () {
      int xf = this.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        return 0;
      }
      int t = this.geti32abs ();
      return xf < 0 ? -t : t;
    }  //efp.geti32

    //------------------------------------------------------------------------
    //i = x.geti32abs ()
    //  abs(x)&0xffffffff
    //  絶対値の整数部の下位32bit
    //
    public int geti32abs () {
      int xf = this.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        return 0;
      }
      //±0,±Inf,NaN以外
      //   -2                               | 0.0ddd dddd dccc cccc c000 0000 0
      //   -1                             0 + 0.dddd dddd cccc cccc 0000 0000
      //    0                d>>>63 +         d.dddd dddc cccc ccc0 0000 000
      //   30                       |       ddd.dddd dccc cccc c000 0000 0
      //   31                       |      dddd.dddd cccc cccc 0000 0000
      //   32                       |    d dddd.dddc cccc ccc0 0000 000
      //   62                       |  ddd dddd.dccc cccc c000 0000 0
      //   63                 d>>>0 + dddd dddd.cccc cccc 0000 0000
      //   64       d<<1|c>>>63 +   d dddd dddc.cccc ccc0 0000 000
      //   94      d<<31|c>>>33 + ddd dddd dccc.cccc c000 0000 0
      //   95      c>>>32 +      dddd dddd cccc.cccc 0000 0000
      //   96             |    d dddd dddc cccc.ccc0 0000 000
      //  126       c>>>1 +  ddd dddd dccc cccc.c000 0000 0
      //  127               dddd dddd cccc cccc.0000 0000 + c<<0
      //  128             d dddd dddc cccc ccc0.0000 000  |
      //  158           ddd dddd dccc cccc c000.0000 0    + c<<31
      //  159          dddd dddd cccc cccc 0000.0000 + 0
      //  160        d dddd dddc cccc ccc0 0000.000  |
      //  190      ddd dddd dccc cccc c000 0000.0    |
      //  191     dddd dddd cccc cccc 0000 0000.0    |
      //  192   d dddd dddc cccc ccc0 0000 0000.0    |
      //                                   ^^^^
      int xe = this.epp;
      long xd = this.dvl;
      long xc = this.cvl;
      return (xe <= -1 ? 0 :
              xe <= 63 ? (int) (xd >>> (63 - xe)) :
              xe <= 94 ? (int) (xd << (xe - 63) | xc >>> (127 - xe)) :
              xe <= 126 ? (int) (xc >>> (127 - xe)) :
              xe <= 158 ? (int) (xc << (xe - 127)) :
              0);
    }  //efp.geti32abs

    //------------------------------------------------------------------------
    //l = x.geti64 ()
    //  x&0xffffffffffffffffL
    //  整数部の下位64bit
    //
    public long geti64 () {
      int xf = this.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        return 0L;
      }
      long t = this.geti64abs ();
      return xf < 0 ? -t : t;
    }  //efp.geti64

    //------------------------------------------------------------------------
    //l = x.geti64abs ()
    //  abs(x)&0xffffffffffffffffL
    //  絶対値の整数部の下位64bit
    //
    public long geti64abs () {
      int xf = this.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        return 0L;
      }
      //±0,±Inf,NaN以外
      //   -2                               | 0.0ddd dddd dccc cccc c000 0000 0
      //   -1                             0 + 0.dddd dddd cccc cccc 0000 0000
      //    0                d>>>63 +         d.dddd dddc cccc ccc0 0000 000
      //   30                       |       ddd.dddd dccc cccc c000 0000 0
      //   31                       |      dddd.dddd cccc cccc 0000 0000
      //   32                       |    d dddd.dddc cccc ccc0 0000 000
      //   62                       |  ddd dddd.dccc cccc c000 0000 0
      //   63                 d>>>0 + dddd dddd.cccc cccc 0000 0000
      //   64  d<<1|c>>>63 +        d dddd dddc.cccc ccc0 0000 000
      //   94              |      ddd dddd dccc.cccc c000 0000 0
      //   95              |     dddd dddd cccc.cccc 0000 0000
      //   96              |   d dddd dddc cccc.ccc0 0000 000
      //  126  d<<63|c>>>1 + ddd dddd dccc cccc.c000 0000 0
      //  127               dddd dddd cccc cccc.0000 0000 + c<<0
      //  128             d dddd dddc cccc ccc0.0000 000  |
      //  158           ddd dddd dccc cccc c000.0000 0    |
      //  159          dddd dddd cccc cccc 0000.0000      |
      //  160        d dddd dddc cccc ccc0 0000.000       |
      //  190      ddd dddd dccc cccc c000 0000.0         + c<<63
      //  191     dddd dddd cccc cccc 0000 0000.0 + 0
      //  192   d dddd dddc cccc ccc0 0000 0000.0 |
      //                              ^^^^ ^^^^
      int xe = this.epp;
      long xd = this.dvl;
      long xc = this.cvl;
      return (xe <= -1 ? 0L :
              xe <= 63 ? (xd >>> (63 - xe)) :
              xe <= 126 ? (xd << (xe - 63) | xc >>> (127 - xe)) :
              xe <= 190 ? (xc << (xe - 127)) :
              0L);
    }  //efp.geti64abs

    //------------------------------------------------------------------------
    //l = x.getl ()
    //  long値
    //
    //  丸めモードを省略したときは小数点以下を切り捨てる(RZ)
    //  2^63-1よりも大きい数は2^63-1に、-2^63よりも小さい数は-2^63に変換する(飽和変換)
    //  NaNは0に変換する
    //
    public long getl () {
      int xf = this.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        if (xf << 1 < 0) {  //±0
          return 0L;
        } else if (xf << 2 < 0) {  //±Inf
          epbFpsr |= EPB_FPSR_OE;
          epbExceptionOperandExponent = xf & M | 0x7fff << 16;
          epbExceptionOperandMantissa = 0x0000000000000000L;
          return xf < 0 ? MSB : ~MSB;  //+Infは0x7fffffffffffffffL,-Infは0x8000000000000000L
        } else {  //NaN
          epbFpsr |= EPB_FPSR_OE;
          epbExceptionOperandExponent = 0x7fff << 16;
          epbExceptionOperandMantissa = 0xffffffffffffffffL;
          return 0L;  //NaNは0L
        }
      }
      //±0,±Inf,NaN以外
      int xe = this.epp;
      if (xe < 0) {  //0<|x|<1
        return 0L;
      }
      //1<=|x|
      if (xe < 63) {  //1<=|x|<2^63
        return xf >= 0 ? this.dvl >>> ~xe : -(this.dvl >>> ~xe);
      }
      //2^63<=|x|
      if (xf >= 0) {  //2^63<=x
        epbFpsr |= EPB_FPSR_OE;
        epbExceptionOperandExponent = 0x3fff + xe << 16;
        epbExceptionOperandMantissa = this.dvl;
        return 0x7fffffffffffffffL;
      }
      //x<=-2^63
      if (xe != 63 || this.dvl != MSB || this.cvl != 0L) {  //x!=-2^63
        epbFpsr |= EPB_FPSR_OE;
        epbExceptionOperandExponent = M | 0x3fff + xe << 16;
        epbExceptionOperandMantissa = this.dvl;
      }
      return 0x8000000000000000L;
    }  //efp.getl()
    public long getl (int roundingMode) {
      return (roundingMode == EPB_MODE_RN ? new EFP ().inner ().rint (this).outer ().getl () :
              roundingMode == EPB_MODE_RM ? new EFP ().inner ().floor (this).outer ().getl () :
              roundingMode == EPB_MODE_RP ? new EFP ().inner ().ceil (this).outer ().getl () :
              this.getl ());
    }  //efp.getl(int)

    //------------------------------------------------------------------------
    //x = x.getman ()
    //y = y.getman (x)
    //  仮数部
    //
    //  getman(±0)=±0, getman(±Inf)=NaN, getman(NaN)=NaN
    //
    public final EFP getman () {
      return this.getman (this);
    }  //efp.getman()
    public final EFP getman (EFP x) {
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        if (xf << 2 < 0) {  //±Inf
          epbFpsr |= EPB_FPSR_OE;
          epbExceptionOperandExponent = xf & M | 0x7fff << 16;
          epbExceptionOperandMantissa = 0x0000000000000000L;
          this.flg = N;  //getman(±Inf)=NaN
        } else {  //±0,NaN
          this.flg = xf;  //getman(±0)=±0, getman(NaN)=NaN
        }
        return this;
      }
      this.flg = xf;  //仮数部
      this.epp = 0;
      this.dvl = x.dvl;
      this.cvl = x.cvl;
      return this;
    }  //efp.getman(EFP)

    //------------------------------------------------------------------------
    //b = x.getp012 (b, a)
    //b = x.getp012 (b, a, k)
    //ib = x.getp012 (ib, ia)
    //ib = x.getp012 (ib, ia, k)
    //  packed値
    //
    //  0
    //    bit31     仮数部の符号(0=+,1=-)
    //    bit30     指数部の符号(0=+,1=-)
    //    bit29-28  ±Inf,NaNのときはすべて1、それ以外はすべて0
    //    bit27-16  指数部(BCD)、±0のときはすべて0、±Inf,NaNのときはすべて1
    //    bit15-12  出力するときは指数部の1000の位、入力するときは不定。±Infのときはすべて0にしておかないとFLOAT4.Xが誤動作する
    //    bit11-4   不定。±Infのときはすべて0にしておかないとFLOAT4.Xが誤動作する
    //    bit3-0    整数部(BCD)、±0,±Infのときはすべて0、NaNのときはすべて1
    //  12
    //    bit63-0   小数部(BCD)、±0,±Infのときはすべて0、NaNのときはすべて1、ただしSNaNのときはbit63だけ0
    //
    //  k-factor
    //    -64..0   -小数点以下の桁数(%f)。0ではない先頭の数字から小数点以下-k桁目までの桁数(1桁以上17桁以下)を有効桁数とする
    //      1..17  有効桁数(%e)
    //     18..63  OPERR
    //
    public byte[] getp012 (byte[] b, int a) {
      return getp012 (b, a, 17);
    }  //efp.getp012(byte[],int)
    public byte[] getp012 (byte[] b, int a, int k) {
      int[] ib = getp012 (new int[3], 0, k);
      int i = ib[0];
      b[a] = (byte) (i >> 24);
      b[a + 1] = (byte) (i >> 16);
      b[a + 2] = (byte) (i >> 8);
      b[a + 3] = (byte) i;
      i = ib[1];
      b[a + 4] = (byte) (i >> 24);
      b[a + 5] = (byte) (i >> 16);
      b[a + 6] = (byte) (i >> 8);
      b[a + 7] = (byte) i;
      i = ib[2];
      b[a + 8] = (byte) (i >> 24);
      b[a + 9] = (byte) (i >> 16);
      b[a + 10] = (byte) (i >> 8);
      b[a + 11] = (byte) i;
      return b;
    }  //efp.getp012(byte[],int,int)
    public int[] getp012 (int[] ib, int ia) {
      return getp012 (ib, ia, 17);
    }  //efp.getp012(int[],int)
    public int[] getp012 (int[] ib, int ia, int k) {
      k = k << -7 >> -7;  //下位7bitを符号拡張する
      int u;
      long v;
      int xf = this.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        if (xf << 1 < 0) {  //±0
          u = xf & M;
          v = 0L;
        } else if (xf << 2 < 0) {  //±Inf
          u = (xf & M) | 0x7fff0000;
          v = 0L;
        } else {  //NaN
          u = 0x7fff0000;
          v = 0xffffffffffffffffL;
        }
      } else {  //±0,±Inf,NaN以外
        if (k > 17) {
          epbFpsr |= EPB_FPSR_OE;
          epbExceptionOperandExponent = this.flg & M | 0x3fff + this.epp << 16;
          epbExceptionOperandMantissa = this.dvl;
          k = 17;
        }
        //  2進数で仮数部が64桁のextendedは2^n*5^27を正確に表現できる
        //  10進数で仮数部が17桁のpackedは2^56*10^nを正確に表現できる
        //  どちらも正確に表現できる2^56*10^27=2^83*5^27のextendedとpackedの相互変換は誤差なしで行われなければならない
        //    2^56*10^27=72057594037927936000000000000000000000000000(44桁)
        //      extended  40900000CECB8F27F4200F3A
        //      packed    004300072057594037927936
        //  同様に2^56*10^34=2^90*5^34のtripleとpackedの相互変換は誤差なしで行われなければならない
        //    2^56*10^34=720575940379279360000000000000000000000000000000000(51桁)
        //      triple    40A7C732F684DF56C3E01BC6
        //      packed    005000072057594037927936
        int xe = this.epp;
        long xd = this.dvl;
        long xc = this.cvl;
        EFP x = new EFP (P, xe, xd, xc);  //絶対値のコピー
        int savedFpsr = epbFpsr;
        this.inner ();
        //10の指数を決める
        //  1.0*2^xe <= x < 2.0*2^xe
        //  1.0*10^(log10(2)*xe) <= x < 2.0*10^(log10(2)*xe)
        //  e=floor(log10(2)*xe)
        //  1.0*10^e <= x < 2.0*10^(e+1)
        //  1.0*10^e <= x < 20.0*10^e
        int e = (int) Math.floor (0.30102999566398119521373889472449302677 * xe);
        //整数部を0桁から20桁にする
        //  常に1桁まで割ってしまうとpackedで表現できる整数の処理中に端数が生じてX2がセットされてしまう
        if (e < 0) {  //10^-eを掛ける。結果は10^0<=x<2*10^1で整数部が1桁または2桁になる。誤差で0桁になる場合がある
          int o = -e;
          EFP t = new EFP (ONE);
          for (int i = 0; o != 0; i++, o >>>= 1) {
            if ((o & 1) != 0) {
              t.imul (EFP_TEN_POWER_P[i]);
            }
          }
          x.imul (t);
        } else if (e <= 18) {  //そのまま。10^0<=x<20*10^18で整数部は1桁から20桁
          e = 0;
        } else {  //10^(e-18)で割る。結果は10^18<=x<20*10^18で整数部が19桁または20桁になる。誤差で18桁になる場合がある
          int o = e -= 18;
          EFP t = new EFP (ONE);
          for (int i = 0; o != 0; i++, o >>>= 1) {
            if ((o & 1) != 0) {
              t.imul (EFP_TEN_POWER_P[i]);
            }
          }
          x.div (t);
        }
        //整数部を展開する
        //  最大65bitの整数を10000で割って16桁の商と4桁の余りに分けてそれぞれBCDに変換する
        //  20^10^18-1=0x1158E460913CFFFFF(65bit)
        u = 0;
        v = 0L;
        if (0 <= x.epp) {  //整数部が1..65bit
          //整数部をs,tに取り出す
          long s, t;
          if (x.epp <= 63) {  //1..64bit
            s = 0L;
            t = x.dvl >>> ~x.epp;
          } else {  //65bit
            s = 1L;  //最上位は1
            t = x.dvl << 1 | x.cvl >>> -1;
          }
          //最大65bitの整数を10000で割る
          long r = s << 32 | t >>> 32;  //上位の被除数
          s = r / 10000L;  //上位の商
          r = r - s * 10000L << 32 | t & 0xffffffffL;  //下位の被除数
          t = r / 10000L;  //下位の商
          v = XEiJ.FMT_BCD4[(int) (r - t * 10000L)];  //下位の余り→下位4桁
          t = XEiJ.fmtBcd16 (s << 32 | t);  //全体の商→上位16桁
          u = (int) (t >>> 48);
          v |= t << 16;
        }
        //小数部を展開する
        //  整数部が18桁以上になるまで小数部を10000倍して整数部を4桁のBCDに変換することを繰り返す
        while ((u & 0xfffffff0) == 0) {
          u = u << 16 | (int) (v >>> -16);
          v = v << 16 | XEiJ.FMT_BCD4[x.frac ().muli (10000).geti32abs ()];
          e -= 4;
        }
        long rest = x.frac ().iszero () ? 0L : 1L;  //k+2桁目以降の端数の有無
        this.outer ();
        epbFpsr = savedFpsr;
        //四捨五入する位を確認する
        //   lz(u)  >>>2  24-
        //  12..15     3   21
        //  16..19     4   20
        //  20..23     5   19
        //  24..27     6   18
        int w = 24 - (Integer.numberOfLeadingZeros (u) >>> 2);  //展開された桁数。18桁以上21桁以下
        //  w桁のBCD値がu:vの96bitに右寄せで格納されている
        //  値はw桁のBCD値*10^e
        if (k <= 0) {  //固定小数点形式のとき
          //  先頭の数字の左側は右からw桁の位置
          //  小数点は右から-e桁の位置
          //  小数点以下-k桁の数字の右側は右から-e+k桁の位置
          //  先頭から小数点以下-k桁までの桁数はw-(-e+k)桁
          k = Math.max (1, Math.min (17, w + e - k));
        }
        //k+2桁目以降の端数の有無を確認する
        int i = w - k - 1 << 2;  //k+1桁目の右から数えたbit位置
        if (0 < i) {  //k+2桁目が展開されている
          if (i < 64) {  //k+1桁目がvにある。k+2桁目以降はvの右端からvの途中まで
            long mask = -1L << i;
            rest |= v & ~mask;  //k+2桁目以降の端数の有無
            v &= mask;
          } else {  //k+1桁目がuにある。k+2桁目以降はvの全体のみまたはvの全体とuの右端から途中まで
            int mask = -1 << i - 64;
            rest |= (long) (u & ~mask) | v;  //k+2桁目以降の端数の有無
            u &= mask;
            v = 0L;
          }
        }
        //k+1桁目を四捨五入する
        int d = (i < 64 ? (int) (v >>> i) : u >>> i - 64) & 15;  //k+1桁目の数字
        if (d != 0 || rest != 0L) {  //k+1桁目以降に端数がある
          epbFpsr |= EPB_FPSR_X2;  //不正確な結果
          epbExceptionOperandExponent = xf & M | 0x3fff + xe << 16;
          epbExceptionOperandMantissa = xd;
          if (i < 64) {
            v &= ~(15L << i);
          } else {
            u &= ~(15 << i);
          }
          i += 4;  //k桁目の右から数えたbit位置
          if ((epbRoundingMode == EPB_MODE_RN &&
               (5 < d ||  //k+1桁目以降に端数があってRNでk+1桁目が5より大きいか、
                (d == 5 && (rest != 0L ||  //k+1桁目が5でk+2桁目以降に端数があるか、
                            ((i < 64 ? (int) (v >>> i) : u >>> i - 64) & 1) != 0)))) ||  //k+1桁目が5でk+2桁目以降に端数がなくてk桁目が奇数または
              (epbRoundingMode == EPB_MODE_RM && xf < 0) ||  //k+1桁目以降に端数があってRMで負または
              (epbRoundingMode == EPB_MODE_RP && 0 <= xf)) {  //k+1桁目以降に端数があってRPで正のとき切り上げる
            //k桁目が9のとき0に変えて切り上げる
            //  切り上げたときk-1桁目が9のとき0に変えて切り上げる
            //    先頭に0があるので必ず止まる
            while (((i < 64 ? (int) (v >>> i) : u >>> i - 64) & 15) == 9) {
              if (i < 64) {
                v &= ~(15L << i);
              } else {
                u &= ~(15 << i);
              }
              i += 4;
            }
            //9でなければ1を加える
            //  先頭の0が1に変わって1桁増える場合がある
            if (i < 64) {
              v += 1L << i;
            } else {
              u += 1 << i;
            }
          }  //切り上げる
        }  //if 端数がある
        //小数点の位置を合わせる
        w = 7 - (Integer.numberOfLeadingZeros (u) >>> 2);  //四捨五入した後の多すぎる小数点以下の桁数
        e += 16 + w;
        i = w << 2;  //多すぎるbit数
        v = (long) u << -i | v >>> i;
        u >>>= i - 64;
        //指数部を展開する
        if (e < 0) {
          u |= 0x40000000;  //指数部の符号
          e = -e;
        }
        e = XEiJ.fmtBcd8 (e);
        if ((e & ~0xfff) != 0) {  //指数部が3桁に収まっていない
          epbFpsr |= EPB_FPSR_OE;
          epbExceptionOperandExponent = xf & M | 0x3fff + xe << 16;
          epbExceptionOperandMantissa = xd;
        }
        u |= (e & 0xfff) << 16 | (e & 0xf000);
        //符号を付ける
        u |= xf & M;  //仮数部の符号
      }
      ib[ia] = u;
      ib[ia + 1] = (int) (v >> 32);
      ib[ia + 2] = (int) v;
      return ib;
    }  //efp.getp012(int[],int,int)

    //------------------------------------------------------------------------
    //i = x.gets ()
    //i = x.gets (roundingMode)
    //  short値
    //
    //  丸めモードを省略したときは小数点以下を切り捨てる(RZ)
    //  2^15-1よりも大きい数は2^15-1に、-2^15よりも小さい数は-2^15に変換する(飽和変換)
    //  NaNは-1に変換する
    //
    //  Javaのdoubleからshortへのキャストは飽和変換ではない(intに飽和変換してから下位16bitを取り出す)ことに注意
    //
    public int gets () {
      int xf = this.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        if (xf << 1 < 0) {  //±0
          return 0;
        } else if (xf << 2 < 0) {  //±Inf
          epbFpsr |= EPB_FPSR_OE;
          epbExceptionOperandExponent = xf & M | 0x7fff << 16;
          epbExceptionOperandMantissa = 0x0000000000000000L;
          return xf >> 31 ^ 0x00007fff;  //+Infは0x00007fff,-Infは0xffff8000
        } else {  //NaN
          epbFpsr |= EPB_FPSR_OE | EPB_FPSR_AV;
          epbExceptionOperandExponent = 0x7fff << 16;
          epbExceptionOperandMantissa = 0xffffffffffffffffL;
          return -1;  //NaNは-1
        }
      }
      //±0,±Inf,NaN以外
      int xe = this.epp;
      long xd = this.dvl;
      long xc = this.cvl;
      if (xe < 0) {  //0<|x|<1
        if (false) {
          epbFpsr |= EPB_FPSR_X2;  //不正確な結果
          epbExceptionOperandExponent = xf | 0x3fff + xe << 16;
          epbExceptionOperandMantissa = xd;
        }
        return 0;
      }
      //1<=|x|
      if (xe < 15) {  //1<=|x|<2^15
        if (false) {
          if ((xd << 1 + xe | xc) != 0L) {  //端数がある
            epbFpsr |= EPB_FPSR_X2;  //不正確な結果
            epbExceptionOperandExponent = xf | 0x3fff + xe << 16;
            epbExceptionOperandMantissa = xd;
          }
        }
        return xf >= 0 ? (int) (xd >>> ~xe) : -(int) (xd >>> ~xe);
      }
      //2^15<=|x|
      if (xf >= 0) {  //2^15<=x
        epbFpsr |= EPB_FPSR_OE;
        epbExceptionOperandExponent = 0x3fff + xe << 16;
        epbExceptionOperandMantissa = xd;
        return 0x00007fff;
      }
      //x<=-2^15
      if (xe != 15 || xd != MSB || xc != 0L) {  //x!=-2^15
        epbFpsr |= EPB_FPSR_OE;
        epbExceptionOperandExponent = M | 0x3fff + xe << 16;
        epbExceptionOperandMantissa = this.dvl;
      }
      return 0xffff8000;
    }  //efp.gets()
    public int gets (int roundingMode) {
      return (roundingMode == EPB_MODE_RN ? new EFP ().inner ().rint (this).outer ().gets () :
              roundingMode == EPB_MODE_RM ? new EFP ().inner ().floor (this).outer ().gets () :
              roundingMode == EPB_MODE_RP ? new EFP ().inner ().ceil (this).outer ().gets () :
              new EFP ().inner ().trunc (this).outer ().gets ());
    }  //efp.gets(int)

    //------------------------------------------------------------------------
    //i = x.getx0 ()
    //i = x.getx0 (roundingMode)
    //l = x.getx12 ()
    //l = x.getx12 (roundingMode)
    //b = x.getx012 (b, a)
    //b = x.getx012 (b, a, roundingMode)
    //ib = x.getx012 (ib, ia)
    //ib = x.getx012 (ib, ia, roundingMode)
    //  extended値
    //
    //         0          1       2
    //    0x7fff0000,0xffffffffffffffffL  Non-Signaling NaN
    //    0x7fff0000,0xbfffffffffffffffL  Signaling NaN
    //    0x7fff0000,0x0000000000000000L  +Inf
    //    0x7ffe0000,0xffffffffffffffffL  2^16384-2^16320   = 1.1897314953572317650212638530309702052 E4932   正規化数の最大値
    //    0x3fff0000,0x8000000000000000L  2^0               = 1
    //    0x00000000,0x8000000000000000L  2^-16383          = 1.6810515715560467531313389086608763013 E-4932  正規化数の最小値
    //    0x00000000,0x7fffffffffffffffL  2^-16383-2^-16446 = 1.6810515715560467529490789320667525712 E-4932  非正規化数の最大値
    //    0x00000000,0x0000000000000001L  2^-16446          = 1.8225997659412373012642029668097099082 E-4951  非正規化数の最小値
    //    0x00000000,0x0000000000000000L  +0
    //    NaNの符号はDon't Care、出力は0
    //    NaNの整数部はDon't Care、出力は1
    //    Non-Signaling NaNの小数部の先頭は1
    //    Signaling NaNの小数部の先頭は0
    //      Signaling NaNが返ることはない
    //    NaNの小数部の先頭以外はNon-Zero、出力はすべて1
    //    ±Infの整数部はDon't Care、出力は0
    //    ±Infの小数部はすべて0
    //    正規化数の整数部は1
    //    非正規化数の整数部は0
    //
    //  メモ
    //    M68000PRMとMC68881UMにはextendedの正規化数の最大値と正規化数の最小値と非正規化数の最小値の記述が間違っているものがある
    //
    public final int getx0 () {
      int[] ib = getx012 (new int[3], 0, EPB_MODE_RN);
      return ib[0];
    }  //efp.getx0()
    public final int getx0 (int roundingMode) {
      int[] ib = getx012 (new int[3], 0, roundingMode);
      return ib[0];
    }  //efp.getx0(int)
    public final long getx12 () {
      int[] ib = getx012 (new int[3], 0, EPB_MODE_RN);
      return (long) ib[1] << 32 | (0xffffffffL & ib[2]);
    }  //efp.getx12()
    public final long getx12 (int roundingMode) {
      int[] ib = getx012 (new int[3], 0, roundingMode);
      return (long) ib[1] << 32 | (0xffffffffL & ib[2]);
    }  //efp.getx12(int)
    public final byte[] getx012 (byte[] b, int a) {
      return getx012 (b, a, EPB_MODE_RN);
    }  //efp.getx012(byte[],int)
    public final byte[] getx012 (byte[] b, int a, int roundingMode) {
      int[] ib = getx012 (new int[3], 0, roundingMode);
      int i = ib[0];
      b[a] = (byte) (i >> 24);
      b[a + 1] = (byte) (i >> 16);
      b[a + 2] = (byte) (i >> 8);
      b[a + 3] = (byte) i;
      i = ib[1];
      b[a + 4] = (byte) (i >> 24);
      b[a + 5] = (byte) (i >> 16);
      b[a + 6] = (byte) (i >> 8);
      b[a + 7] = (byte) i;
      i = ib[2];
      b[a + 8] = (byte) (i >> 24);
      b[a + 9] = (byte) (i >> 16);
      b[a + 10] = (byte) (i >> 8);
      b[a + 11] = (byte) i;
      return b;
    }  //efp.getx012(byte[],int,int)
    public final int[] getx012 (int[] ib, int ia) {
      return this.getx012 (ib, ia, EPB_MODE_RN);
    }  //efp.getx012(int[],int)
    public final int[] getx012 (int[] ib, int ia, int roundingMode) {
      int xf = this.flg;
      int xe = this.epp;  //正規化数は-16383<=xe<=16383、非正規化数は-16446<=xe<=-16384
      long xd = this.dvl;
      long xc = this.cvl;
    xfxd:
      {
        if (xf << 1 != 0) {  //±0,±Inf,NaN
          if (xf << 1 < 0) {  //±0
            xf &= M;  //符号部1bit、指数部15bit、空き16bit
            xd = 0x0000000000000000L;  //整数部1bit、小数部63bit
          } else if (xf << 2 < 0) {  //±Inf
            xf = (xf & M) | 0x7fff0000;  //符号部1bit、指数部15bit、空き16bit
            xd = 0x0000000000000000L;  //整数部1bit、小数部63bit
          } else {  //NaN
            xf = 0x7fff0000;  //符号部1bit、指数部15bit、空き16bit
            xd = 0xffffffffffffffffL;  //整数部1bit、小数部63bit
          }
          break xfxd;
        }
        //±0,±Inf,NaN以外
        if (xe < -16447) {  //指数部が小さすぎる。非正規化数の最小値は2^-16446だが丸めで繰り上がる場合があるので一旦2^-16447まで受け入れる
          epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
          epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
          epbExceptionOperandMantissa = xd;
          if (0 <= xf) {  //+x
            if (roundingMode == EPB_MODE_RP) {  //RPのとき+eps
              xf = 0x00000000;  //符号部1bit、指数部15bit、空き16bit
              xd = 0x0000000000000001L;  //整数部1bit、小数部63bit
            } else {  //RN,RZ,RMのとき+0
              xf = 0x00000000;  //符号部1bit、指数部15bit、空き16bit
              xd = 0x0000000000000000L;  //整数部1bit、小数部63bit
            }
          } else {  //-x
            if (roundingMode == EPB_MODE_RM) {  //RMのとき-eps
              xf = 0x80000000;  //符号部1bit、指数部15bit、空き16bit
              xd = 0x0000000000000001L;  //整数部1bit、小数部63bit
            } else {  //RN,RZ,RPのとき-0
              xf = 0x80000000;  //符号部1bit、指数部15bit、空き16bit
              xd = 0x0000000000000000L;  //整数部1bit、小数部63bit
            }
          }
          break xfxd;
        }
        if (16383 < xe) {  //指数部が大きすぎる
          if (true) {
            epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
            if (xc != 0L) {  //端数が0ではない
              epbFpsr |= EPB_FPSR_X2;  //不正確な結果
            }
          } else {
            epbFpsr |= EPB_FPSR_OF | EPB_FPSR_X2;  //オーバーフロー、不正確な結果
          }
          epbExceptionOperandExponent = xf | 0x3fff - 0x6000 + xe << 16;
          epbExceptionOperandMantissa = xd;
          if (0 <= xf) {  //+x
            if (roundingMode == EPB_MODE_RM) {  //RMのとき+max
              xf = 0x7ffe0000;  //符号部1bit、指数部15bit、空き16bit
              xd = 0xffffffffffffffffL;  //整数部1bit、小数部63bit
            } else {  //RN,RZ,RPのとき+Inf
              xf = 0x7fff0000;  //符号部1bit、指数部15bit、空き16bit
              xd = 0x0000000000000000L;  //整数部1bit、小数部63bit
            }
          } else {  //-x
            if (roundingMode == EPB_MODE_RP) {  //RPのとき-max
              xf = 0xfffe0000;  //符号部1bit、指数部15bit、空き16bit
              xd = 0xffffffffffffffffL;  //整数部1bit、小数部63bit
            } else {  //RN,RZ,RMのとき-Inf
              xf = 0xffff0000;  //符号部1bit、指数部15bit、空き16bit
              xd = 0x0000000000000000L;  //整数部1bit、小数部63bit
            }
          }
          break xfxd;
        }
        long xb = 0L;
        int o = xe <= -16384 ? 0 + -16383 - xe : 0;  //右にずらすbit数。正規化数は0、非正規化数は0+1<=o<=0+64
        if (o == 0) {
        } else if (o < 64) {
          xb = xc << -o;
          xc = xd << -o | xc >>> o;
          xd >>>= o;
        } else {
          xb = xc;
          xc = xd;
          xd = 0L;
        }
        if ((xc | xb) != 0L) {  //端数が0ではない
          epbFpsr |= EPB_FPSR_X2;  //不正確な結果
          if (roundingMode == EPB_MODE_RN && xc < 0L && (xd << 63 | xc << 1 | xb) != 0L ||  //RNでguard bitが1かつLSBまたはguard bit以外の端数が0ではないまたは
              roundingMode == EPB_MODE_RM && xf < 0 ||  //端数が0ではなくてRMで-または
              roundingMode == EPB_MODE_RP && 0 <= xf) {  //端数が0ではなくてRPで+のとき
            xd++;  //繰り上げる
            if (xd == 0L) {  //繰り上がって溢れたとき
              xd = MSB;
              xe++;  //指数部をインクリメントする。ここでxe=16384になる場合がある
              if (16383 < xe) {  //指数部が大きすぎる
                epbFpsr |= EPB_FPSR_OF | EPB_FPSR_X2;  //オーバーフロー、不正確な結果
                epbExceptionOperandExponent = xf | 0x3fff - 0x6000 + xe << 16;
                epbExceptionOperandMantissa = xd;
                if (0 <= xf) {  //+x
                  if (roundingMode == EPB_MODE_RM) {  //RMのとき+max
                    xf = 0x7ffe0000;  //符号部1bit、指数部15bit、空き16bit
                    xd = 0xffffffffffffffffL;  //整数部1bit、小数部63bit
                  } else {  //RN,RZ,RPのとき+Inf
                    xf = 0x7fff0000;  //符号部1bit、指数部15bit、空き16bit
                    xd = 0x0000000000000000L;  //整数部1bit、小数部63bit
                  }
                } else {  //-x
                  if (roundingMode == EPB_MODE_RP) {  //RPのとき-max
                    xf = 0xfffe0000;  //符号部1bit、指数部15bit、空き16bit
                    xd = 0xffffffffffffffffL;  //整数部1bit、小数部63bit
                  } else {  //RN,RZ,RMのとき-Inf
                    xf = 0xffff0000;  //符号部1bit、指数部15bit、空き16bit
                    xd = 0x0000000000000000L;  //整数部1bit、小数部63bit
                  }
                }
                break xfxd;
              }  //if 指数部が大きすぎる
            } else if (0 < o) {  //非正規化数のとき
              if (xd << o - 1 < 0L) {  //1bit増えたとき
                xe++;  //指数部をインクリメントする
/* getx012
                if (xe == -16383) {  //非正規化数が繰り上がって正規化数になったとき
                  //xd = 1L << 15;
                  epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
                  epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
                  epbExceptionOperandMantissa = xd;
                }
*/
              }
            }
          }
          //RZ toward zeroのときは端数を切り捨てるだけなので何もしなくてよい
          if (xe <= -16384) {  //非正規化数
            epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
            epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
            epbExceptionOperandMantissa = xd;
            if (xd == 0L) {  //非正規化数でxe==-16447だったとき、先頭の1がxcにあって丸めで繰り上がらなかった
              if (0 <= xf) {  //+x
                if (roundingMode == EPB_MODE_RP) {  //RPのとき+eps
                  xf = 0x00000000;  //符号部1bit、指数部15bit、空き16bit
                  xd = 0x0000000000000001L;  //整数部1bit、小数部63bit
                } else {  //RN,RZ,RMのとき+0
                  xf = 0x00000000;  //符号部1bit、指数部15bit、空き16bit
                  xd = 0x0000000000000000L;  //整数部1bit、小数部63bit
                }
              } else {  //-x
                if (roundingMode == EPB_MODE_RM) {  //RMのとき-eps
                  xf = 0x80000000;  //符号部1bit、指数部15bit、空き16bit
                  xd = 0x0000000000000001L;  //整数部1bit、小数部63bit
                } else {  //RN,RZ,RPのとき-0
                  xf = 0x80000000;  //符号部1bit、指数部15bit、空き16bit
                  xd = 0x0000000000000000L;  //整数部1bit、小数部63bit
                }
              }
              break xfxd;
            }
          }  //if 非正規化数
        } else {  //端数が0
          if (xe <= -16384) {  //非正規化数
            epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
            epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
            epbExceptionOperandMantissa = xd;
            if (xd == 0L) {  //非正規化数でxe==-16447だったとき、先頭の1がxcにあって丸めで繰り上がらなかった
              if (0 <= xf) {  //+x
                if (roundingMode == EPB_MODE_RP) {  //RPのとき+eps
                  xf = 0x00000000;  //符号部1bit、指数部15bit、空き16bit
                  xd = 0x0000000000000001L;  //整数部1bit、小数部63bit
                } else {  //RN,RZ,RMのとき+0
                  xf = 0x00000000;  //符号部1bit、指数部15bit、空き16bit
                  xd = 0x0000000000000000L;  //整数部1bit、小数部63bit
                }
              } else {  //-x
                if (roundingMode == EPB_MODE_RM) {  //RMのとき-eps
                  xf = 0x80000000;  //符号部1bit、指数部15bit、空き16bit
                  xd = 0x0000000000000001L;  //整数部1bit、小数部63bit
                } else {  //RN,RZ,RPのとき-0
                  xf = 0x80000000;  //符号部1bit、指数部15bit、空き16bit
                  xd = 0x0000000000000000L;  //整数部1bit、小数部63bit
                }
              }
              break xfxd;
            }
          }  //if 非正規化数
        }  //if 端数が0ではない/端数が0
        xf |= Math.max (0, 16383 + xe) << 16;  //符号とバイアスを加えた指数部
      }  //xfxd
      //結果
      ib[ia] = xf;
      ib[ia + 1] = (int) (xd >> 32);
      ib[ia + 2] = (int) xd;
      return ib;
    }  //efp.getx012(int[],int,int)

    //------------------------------------------------------------------------
    //i = x.gety0 ()
    //i = x.gety0 (roundingMode)
    //l = x.gety12 ()
    //l = x.gety12 (roundingMode)
    //b = x.gety012 (b, a)
    //b = x.gety012 (b, a, roundingMode)
    //ib = x.gety012 (ib, ia)
    //ib = x.gety012 (ib, ia, roundingMode)
    //  triple値
    //
    //         0          1       2
    //    0x7fffffff,0xffffffffffffffffL  Non-Signaling NaN
    //    0x7fffffff,0xbfffffffffffffffL  Signaling NaN
    //    0x7fff0000,0x0000000000000000L  +Inf
    //    0x7ffeffff,0xffffffffffffffffL  2^16384-2^16304   = 1.1897314953572317650857583425051800275 E4932   正規化数の最大値
    //    0x3fff0000,0x8000000000000000L  2^0               = 1
    //    0x00000000,0x8000000000000000L  2^-16383          = 1.6810515715560467531313389086608763013 E-4932  正規化数の最小値
    //    0x0000ffff,0x7fffffffffffffffL  2^-16383-2^-16462 = 1.6810515715560467531313361275943389154 E-4932  非正規化数の最大値
    //    0x00000001,0x0000000000000000L  2^-16462          = 2.7810665373859211750247237652736052066 E-4956  非正規化数の最小値
    //    0x00000000,0x0000000000000000L  +0
    //    NaNの符号はDon't Care、出力は0
    //    NaNの整数部はDon't Care、出力は1
    //    Non-Signaling NaNの小数部の先頭は1
    //    Signaling NaNの小数部の先頭は0
    //      Signaling NaNが返ることはない
    //    NaNの小数部の先頭以外はNon-Zero、出力はすべて1
    //    ±Infの整数部はDon't Care、出力は0
    //    ±Infの小数部はすべて0
    //    正規化数の整数部は1
    //    非正規化数の整数部は0
    //
    public final int gety0 () {
      int[] ib = gety012 (new int[3], 0, EPB_MODE_RN);
      return ib[0];
    }  //efp.gety0()
    public final int gety0 (int roundingMode) {
      int[] ib = gety012 (new int[3], 0, roundingMode);
      return ib[0];
    }  //efp.gety0(int)
    public final long gety12 () {
      int[] ib = gety012 (new int[3], 0, EPB_MODE_RN);
      return (long) ib[1] << 32 | (0xffffffffL & ib[2]);
    }  //efp.gety12()
    public final long gety12 (int roundingMode) {
      int[] ib = gety012 (new int[3], 0, roundingMode);
      return (long) ib[1] << 32 | (0xffffffffL & ib[2]);
    }  //efp.gety12(int)
    public final byte[] gety012 (byte[] b, int a) {
      return gety012 (b, a, EPB_MODE_RN);
    }  //efp.gety012(byte[],int)
    public final byte[] gety012 (byte[] b, int a, int roundingMode) {
      int[] ib = gety012 (new int[3], 0, roundingMode);
      int i = ib[0];
      b[a] = (byte) (i >> 24);
      b[a + 1] = (byte) (i >> 16);
      b[a + 2] = (byte) (i >> 8);
      b[a + 3] = (byte) i;
      i = ib[1];
      b[a + 4] = (byte) (i >> 24);
      b[a + 5] = (byte) (i >> 16);
      b[a + 6] = (byte) (i >> 8);
      b[a + 7] = (byte) i;
      i = ib[2];
      b[a + 8] = (byte) (i >> 24);
      b[a + 9] = (byte) (i >> 16);
      b[a + 10] = (byte) (i >> 8);
      b[a + 11] = (byte) i;
      return b;
    }  //efp.gety012(byte[],int,int)
    public final int[] gety012 (int[] ib, int ia) {
      return this.gety012 (ib, ia, EPB_MODE_RN);
    }  //efp.gety012(int[],int)
    public final int[] gety012 (int[] ib, int ia, int roundingMode) {
      int xf = this.flg;
      int xe = this.epp;  //正規化数は-16383<=xe<=16383、非正規化数は-16462<=xe<=-16384
      long xd = this.dvl;
      long xc = this.cvl;
    xfxd:
      {
        if (xf << 1 != 0) {  //±0,±Inf,NaN
          if (xf << 1 < 0) {  //±0
            xf &= M;  //符号部1bit、指数部15bit、小数部の下位16bit
            xd = 0x0000000000000000L;  //整数部1bit、小数部の上位63bit
          } else if (xf << 2 < 0) {  //±Inf
            xf = (xf & M) | 0x7fff0000;  //符号部1bit、指数部15bit、小数部の下位16bit
            xd = 0x0000000000000000L;  //整数部1bit、小数部の上位63bit
          } else {  //NaN
            xf = 0x7fffffff;  //符号部1bit、指数部15bit、小数部の下位16bit
            xd = 0xffffffffffffffffL;  //整数部1bit、小数部の上位63bit
          }
          break xfxd;
        }
        //±0,±Inf,NaN以外
        if (xe < -16463) {  //指数部が小さすぎる。非正規化数の最小値は2^-16462だが丸めで繰り上がる場合があるので一旦2^-16463まで受け入れる
          epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
          epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
          epbExceptionOperandMantissa = xd;
          if (0 <= xf) {  //+x
            if (roundingMode == EPB_MODE_RP) {  //RPのとき+eps
              xf = 0x00000001;  //符号部1bit、指数部15bit、小数部の下位16bit
              xd = 0x0000000000000000L;  //整数部1bit、小数部の上位63bit
            } else {  //RN,RZ,RMのとき+0
              xf = 0x00000000;  //符号部1bit、指数部15bit、小数部の下位16bit
              xd = 0x0000000000000000L;  //整数部1bit、小数部の上位63bit
            }
          } else {  //-x
            if (roundingMode == EPB_MODE_RM) {  //RMのとき-eps
              xf = 0x80000001;  //符号部1bit、指数部15bit、小数部の下位16bit
              xd = 0x0000000000000000L;  //整数部1bit、小数部の上位63bit
            } else {  //RN,RZ,RPのとき-0
              xf = 0x80000000;  //符号部1bit、指数部15bit、小数部の下位16bit
              xd = 0x0000000000000000L;  //整数部1bit、小数部の上位63bit
            }
          }
          break xfxd;
        }
        if (16383 < xe) {  //指数部が大きすぎる
          if (true) {
            epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
            if (xc << 16 != 0L) {  //端数が0ではない
              epbFpsr |= EPB_FPSR_X2;  //不正確な結果
            }
          } else {
            epbFpsr |= EPB_FPSR_OF | EPB_FPSR_X2;  //オーバーフロー、不正確な結果
          }
          epbExceptionOperandExponent = xf | 0x3fff - 0x6000 + xe << 16;
          epbExceptionOperandMantissa = xd;
          if (0 <= xf) {  //+x
            if (roundingMode == EPB_MODE_RM) {  //RMのとき+max
              xf = 0x7ffeffff;  //符号部1bit、指数部15bit、小数部の下位16bit
              xd = 0xffffffffffffffffL;  //整数部1bit、小数部の上位63bit
            } else {  //RN,RZ,RPのとき+Inf
              xf = 0x7fff0000;  //符号部1bit、指数部15bit、小数部の下位16bit
              xd = 0x0000000000000000L;  //整数部1bit、小数部の上位63bit
            }
          } else {  //-x
            if (roundingMode == EPB_MODE_RP) {  //RPのとき-max
              xf = 0xfffeffff;  //符号部1bit、指数部15bit、小数部の下位16bit
              xd = 0xffffffffffffffffL;  //整数部1bit、小数部の上位63bit
            } else {  //RN,RZ,RMのとき-Inf
              xf = 0xffff0000;  //符号部1bit、指数部15bit、小数部の下位16bit
              xd = 0x0000000000000000L;  //整数部1bit、小数部の上位63bit
            }
          }
          break xfxd;
        }
        long xb = 0L;
        long xa = 0L;
        int o = xe <= -16384 ? 48 + -16383 - xe : 48;  //右にずらすbit数。正規化数は48、非正規化数は48+1<=o<=48+80
        if (o < 64) {
          xb = xc << -o;
          xc = xd << -o | xc >>> o;
          xd >>>= o;
        } else if (o == 64) {
          xb = xc;
          xc = xd;
          xd = 0L;
        } else if (o < 128) {
          xa = xc << -o;
          xb = xd << -o | xc >>> o;
          xc = xd >>> o;
          xd = 0L;
        } else {
          xa = xc;
          xb = xd;
          xc = 0L;
          xd = 0L;
        }
        if ((xb | xa) != 0L) {  //端数が0ではない
          epbFpsr |= EPB_FPSR_X2;  //不正確な結果
          if (roundingMode == EPB_MODE_RN && xb < 0L && (xc << 63 | xb << 1 | xa) != 0L ||  //RNでguard bitが1かつLSBまたはguard bit以外の端数が0ではないまたは
              roundingMode == EPB_MODE_RM && xf < 0 ||  //端数が0ではなくてRMで-または
              roundingMode == EPB_MODE_RP && 0 <= xf) {  //端数が0ではなくてRPで+のとき
            xc++;  //繰り上げる
            if (xc == 0L) {  //繰り上がって溢れたとき
              xd++;  //繰り上げる
              if (xd >>> 16 != 0L) {  //繰り上がって溢れたとき
                //xd = 1L << 15;
                xe++;  //指数部をインクリメントする。ここでxe=16384になる場合がある
                if (16383 < xe) {  //指数部が大きすぎる
                  epbFpsr |= EPB_FPSR_OF | EPB_FPSR_X2;  //オーバーフロー、不正確な結果
                  epbExceptionOperandExponent = xf | 0x3fff - 0x6000 + xe << 16;
                  epbExceptionOperandMantissa = xd;
                  if (0 <= xf) {  //+x
                    if (roundingMode == EPB_MODE_RM) {  //RMのとき+max
                      xf = 0x7ffeffff;  //符号部1bit、指数部15bit、小数部の下位16bit
                      xd = 0xffffffffffffffffL;  //整数部1bit、小数部の上位63bit
                    } else {  //RN,RZ,RPのとき+Inf
                      xf = 0x7fff0000;  //符号部1bit、指数部15bit、小数部の下位16bit
                      xd = 0x0000000000000000L;  //整数部1bit、小数部の上位63bit
                    }
                  } else {  //-x
                    if (roundingMode == EPB_MODE_RP) {  //RPのとき-max
                      xf = 0xfffeffff;  //符号部1bit、指数部15bit、小数部の下位16bit
                      xd = 0xffffffffffffffffL;  //整数部1bit、小数部の上位63bit
                    } else {  //RN,RZ,RMのとき-Inf
                      xf = 0xffff0000;  //符号部1bit、指数部15bit、小数部の下位16bit
                      xd = 0x0000000000000000L;  //整数部1bit、小数部の上位63bit
                    }
                  }
                  break xfxd;
                }  //if 指数部が大きすぎる
              } else if (48 < o) {  //非正規化数のとき
                if (xd << o - 1 < 0L) {  //1bit増えたとき
                  xe++;  //指数部をインクリメントする
/* gety012
                  if (xe == -16383) {  //非正規化数が繰り上がって正規化数になったとき
                    //xd = 1L << 15;
                    epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
                    epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
                    epbExceptionOperandMantissa = xd;
                  }
*/
                }
              }
            }
          }
          //RZ toward zeroのときは端数を切り捨てるだけなので何もしなくてよい
          if (xe <= -16384) {  //非正規化数
            epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
            epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
            epbExceptionOperandMantissa = xd;
            if ((xd | xc) == 0L) {  //非正規化数でxe==-16463だったとき、先頭の1がxbにあって丸めで繰り上がらなかった
              if (0 <= xf) {  //+x
                if (roundingMode == EPB_MODE_RP) {  //RPのとき+eps
                  xf = 0x00000001;  //符号部1bit、指数部15bit、小数部の下位16bit
                  xd = 0x0000000000000000L;  //整数部1bit、小数部の上位63bit
                } else {  //RN,RZ,RMのとき+0
                  xf = 0x00000000;  //符号部1bit、指数部15bit、小数部の下位16bit
                  xd = 0x0000000000000000L;  //整数部1bit、小数部の上位63bit
                }
              } else {  //-x
                if (roundingMode == EPB_MODE_RM) {  //RMのとき-eps
                  xf = 0x80000001;  //符号部1bit、指数部15bit、小数部の下位16bit
                  xd = 0x0000000000000000L;  //整数部1bit、小数部の上位63bit
                } else {  //RN,RZ,RPのとき-0
                  xf = 0x80000000;  //符号部1bit、指数部15bit、小数部の下位16bit
                  xd = 0x0000000000000000L;  //整数部1bit、小数部の上位63bit
                }
              }
              break xfxd;
            }
          }  //if 非正規化数
        } else {  //端数が0
          if (xe <= -16384) {  //非正規化数
            epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
            epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
            epbExceptionOperandMantissa = xd;
            if ((xd | xc) == 0L) {  //非正規化数でxe==-16463だったとき、先頭の1がxbにあって丸めで繰り上がらなかった
              if (0 <= xf) {  //+x
                if (roundingMode == EPB_MODE_RP) {  //RPのとき+eps
                  xf = 0x00000001;  //符号部1bit、指数部15bit、小数部の下位16bit
                  xd = 0x0000000000000000L;  //整数部1bit、小数部の上位63bit
                } else {  //RN,RZ,RMのとき+0
                  xf = 0x00000000;  //符号部1bit、指数部15bit、小数部の下位16bit
                  xd = 0x0000000000000000L;  //整数部1bit、小数部の上位63bit
                }
              } else {  //-x
                if (roundingMode == EPB_MODE_RM) {  //RMのとき-eps
                  xf = 0x80000001;  //符号部1bit、指数部15bit、小数部の下位16bit
                  xd = 0x0000000000000000L;  //整数部1bit、小数部の上位63bit
                } else {  //RN,RZ,RPのとき-0
                  xf = 0x80000000;  //符号部1bit、指数部15bit、小数部の下位16bit
                  xd = 0x0000000000000000L;  //整数部1bit、小数部の上位63bit
                }
              }
              break xfxd;
            }
          }  //if 非正規化数
        }  //if 端数が0ではない/端数が0
        xd = xd << 48 | xc >>> -48;
        xc <<= 48;
        xf |= Math.max (0, 16383 + xe) << 16;  //符号とバイアスを加えた指数部
      }  //xfxd
      //結果
      ib[ia] = xf | (int) (xc >> 48);
      ib[ia + 1] = (int) (xd >> 32);
      ib[ia + 2] = (int) xd;
      return ib;
    }  //efp.gety012(byte[],int,int)

    //------------------------------------------------------------------------
    //b = x.gt (y)
    //  b=x>y
    //  より大きいか
    //
    //  -Inf==-Inf<-x<-0==+0<+x<+Inf==+Inf
    //
    //  NaNの扱い
    //    どちらかがNaNのときはfalseを返す
    //
    public boolean gt (EFP y) {
      int xf = this.flg;
      int yf = y.flg;
      if ((xf | yf) << 1 != 0) {  //どちらかが±0,±Inf,NaN
        return EFP_GT_TABLE[xf >>> 28] << (yf >>> 28 - 1) < 0;
      }
      //両方±0,±Inf,NaN以外
      if (xf != yf) {  //両方±0,±Inf,NaN以外で符号が違う
        return xf > yf;
      }
      //両方±0,±Inf,NaN以外で符号が同じ
      int s;
      long t;
      return (xf >= 0 ? 1 : -1) * ((s = this.epp - y.epp) != 0 ? s >= 0 ? 1 : -1 :
                                   (t = this.dvl - y.dvl) != 0L ? t >= 0L ? 1 : -1 :
                                   (t = (this.cvl >>> 1) - (y.cvl >>> 1)) != 0L ? t >= 0L ? 1 : -1 :
                                   0) > 0;
    }  //efp.gt(EFP)

    //------------------------------------------------------------------------
    //i = x.hashCode ()
    //  ハッシュコード
    //
    //  equalsであるオブジェクトはhashCodeが同じでなければならない
    //  equalsでないオブジェクトはhashCodeがなるべく違う方がよい
    //
    public int hashCode () {
      return (this.flg ^
              this.epp ^
              (int) (this.dvl >> 32) ^
              (int) this.dvl ^
              (int) (this.cvl >> 32));
    }  //efp.hashCode()

    //------------------------------------------------------------------------
    //x = x.ieeerem (y)
    //  x=IEEEremainder(x,y)
    //z = z.ieeerem (x, y)
    //  z=IEEEremainder(x,y)
    //  剰余(round-to-nearest)
    //
    //  JavaのMath.IEEEremainder(x,y)と同じ
    //  IEEEremainder(x,y)=isNaN(x)||isNaN(y)||isInfinite(x)?NaN:isInfinite(y)?x:x-rint(x/y)*y
    //  被除数から最も近い除数の倍数を引いた結果を返す
    //  倍数の符号は任意なので除数の符号は結果に影響しない
    //    IEEEremainder ( 5.0,  3.0) ==  5.0 - rint ( 5.0 /  3.0) *  3.0 == -1.0
    //    IEEEremainder ( 5.0, -3.0) ==  5.0 - rint ( 5.0 / -3.0) * -3.0 == -1.0
    //    IEEEremainder (-5.0,  3.0) == -5.0 - rint (-5.0 /  3.0) *  3.0 ==  1.0
    //    IEEEremainder (-5.0, -3.0) == -5.0 - rint (-5.0 / -3.0) * -3.0 ==  1.0
    //
    public final EFP ieeerem (EFP y) {
      return this.ieeerem (this, y);
    }  //efp.ieeerem(EFP)
    public final EFP ieeerem (EFP x, EFP y) {
      int xf = x.flg;
      int yf = y.flg;
      epbFpsr &= 0xff00ffff;  //quotient byteをクリアする
      if ((xf | yf) << 1 != 0) {  //どちらかが±0,±Inf,NaN
        if ((xf | yf) << 3 < 0) {  //ieeerem(NaN,y)=NaN, ieeerem(x,NaN)=NaN
          this.flg = N;
        } else if (xf << 2 < 0 ||  //ieeerem(±Inf,y)=NaN
                   yf << 1 < 0) {  //ieeerem(x,±0)=NaN
          //除数が±0でもゼロ除算にはならない
          epbFpsr |= EPB_FPSR_OE;
          if (yf << 1 < 0) {  //±0
            epbExceptionOperandExponent = yf & M;
            epbExceptionOperandMantissa = 0x0000000000000000L;
          } else if (yf << 2 < 0) {  //±Inf
            epbExceptionOperandExponent = yf & M | 0x7fff << 16;
            epbExceptionOperandMantissa = 0x0000000000000000L;
          } else {  //±y
            epbExceptionOperandExponent = yf & M | 0x3fff + y.epp << 16;
            epbExceptionOperandMantissa = y.dvl;
          }
          this.flg = N;
        } else if (xf << 1 < 0) {  //ieeerem(±0,y)=±0
          epbFpsr |= ((xf ^ yf) & M) >>> 8;  //quotient byteに商の符号を入れる
          this.flg = xf;
        } else {  //ieeerem(x,±Inf)=x
          epbFpsr |= ((xf ^ yf) & M) >>> 8;  //quotient byteに商の符号を入れる
          this.finish (xf, x.epp, x.dvl, x.cvl, 0L);  //xが非正規化数のときUFをセットする
        }
        return this;
      }
      //両方±0,±Inf,NaN以外
      epbFpsr |= ((xf ^ yf) & M) >>> 8;  //quotient byteに商の符号を入れる
      if (false) {
        this.inner ();
        //this.sub (x, new EFP ().div (x, y).rint ().imul (y));  //x-rint(x/y)*y。this==x||this==yの場合に注意
        EFP q = new EFP ().quo (x, y);  //商
        int qi = q.geti32abs ();  //商の絶対値の下位32bit
        EFP w = new EFP ();
        this.imulw (w, q, y).negsub (x).sub (w);  //余り。桁落ちを避けるため倍精度で計算する
        int k = w.imul2 (this).cmpabs (y);  //|余り*2|<=>|除数|
        if (k > 0 || k == 0 && (qi & 1) != 0) {  //余りの絶対値が除数の絶対値の1/2よりも大きいか、ちょうど1/2で商が奇数のとき
          qi++;  //商の絶対値を1増やす
          if ((xf ^ yf) >= 0) {
            this.sub (y);
          } else {
            this.iadd (y);
          }
        }
        epbQuotient = qi;
        epbFpsr |= (qi & 127) << 16;  //商の絶対値の下位7bit
        if (this.flg << 1 < 0) {  //余りが0
          this.flg = xf | Z;  //0にxの符号を付ける
        }
        return this.outer ().finish ();
      } else {
        this.inner ();
        int ye = y.epp;  //this==yの場合があるので順序に注意する
        long yd = y.dvl;
        long yc = y.cvl;
        long yc1 = yc >>> 1;
        this.epp = x.epp;
        this.dvl = x.dvl;
        this.cvl = x.cvl;
        int i;
        long l;
        int q = 0;
        if ((i = this.epp - ye) > 0 ||
            i == 0 && ((l = this.dvl - yd) > 0L ||
                       l == 0L && this.cvl >>> 1 >= yc1)) {  //|x|>=|y|。商は0ではない
          this.flg = P;  //|x|。余りの初期値
          EFP t = new EFP (P, 0, yd, yc);
          do {
            t.epp = i = (l = this.dvl - yd) > 0L || l == 0L && this.cvl >>> 1 >= yc1 ? this.epp : this.epp - 1;  //指数部を揃えて
            if ((i -= ye) <= 31) {
              q |= 1 << i;
            }
            this.sub (t);  //引く。アンダーフローのチェックは後で行う
          } while (this.flg == 0 &&  //0ではない
                   ((i = this.epp - ye) > 0 ||
                    i == 0 && ((l = this.dvl - yd) > 0L ||
                               l == 0L && this.cvl >>> 1 >= yc1)));  //this>=|y|。まだ引ける。指数部が極端に違うと繰り返す回数が大きくなる
          this.flg |= xf;  //余りが0の場合も含めてyの符号に関係なくxの符号を付ける
        } else {  //|x|<|y|。商は0
          this.flg = xf;  //被除数がそのまま余りになる
        }
        if (this.flg << 1 >= 0) {  //余りが0ではないとき
          if ((i = this.epp - ye + 1) > 0 ||
              i == 0 && ((l = this.dvl - yd) > 0L ||
                         l == 0L && ((l = (this.cvl >>> 1) - yc1) > 0L ||  //|r|>|y|/2または
                                     l == 0L && (q & 1) != 0))) {  //|r|==|y|/2かつ商が奇数
            this.sub (new EFP (this.flg, ye, yd, yc));  //符号を合わせて引く。アンダーフローのチェックは後で行う
            q++;
          }
          if ((short) this.epp != this.epp) {  //アンダーフロー
            this.outer ();
            epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
            epbExceptionOperandExponent = this.flg & M;
            epbExceptionOperandMantissa = this.dvl;
            return this.sete (UNFL_RESULTS[epbRoundingPrec << 3 | epbRoundingMode << 1 | xf >>> 31]).finish ();  //±0
          }
        }
        epbQuotient = q;
        epbFpsr |= (q & 127) << 16;  //商の絶対値の下位7bit
        return this.outer ().finish ();
      }
    }  //efp.ieeerem(EFP,EFP)

    //------------------------------------------------------------------------
    //k = x.ieeerempi2 ()
    //  k=rint(x/(pi/2))&3
    //  x=x-rint(x/(pi/2))*(pi/2)
    //k = y.ieeerempi2 (x)
    //  k=rint(x/(pi/2))&3
    //  y=x-rint(x/(pi/2))*(pi/2)
    //  ラジアンの象限分類
    //
    //  引数をpi/2で割った余りを[-pi/4..pi/4]の範囲で求めて商の下位2bitを返す
    //                     k=1
    //               │    ←
    //    k=2↓\    │    /
    //           \  │  /
    //             \│/
    //       ────・────
    //             /│\
    //           /  │  \
    //         /    │    \↑k=0
    //         →    │
    //        k=3
    //
    //  三角関数に与えられた引数が大きすぎる場合は何かの間違いでその引数と結果は意味を持たないと考えられる
    //  しかし実装としてはどのような引数が与えられても可能な限り真の値に近い結果を返したい
    //  sin(2^n)の象限分類を行うにはおよそ(n)bitの円周率を静的または動的に調達する必要がある
    //    xをyで割った余りx%y=x-trunc(x/y)*yを正確に求めるには商trunc(x/y)を1の位まで正確に求めなければならない
    //    xの指数部に対してyの有効桁数が少ないと商を1の位まで正確に求めることができない
    //    yがpi/2のときxが2^nならばyのpi/2もおよそ(n)bitなければならない
    //  除数が定数のときは除算を逆数乗算で置き換えることができる
    //    除数yがpi/2なのでxの指数部の最大値と同じ桁数の2/piの値があればよい
    //    象限分類で必要なのは商の下位2bitと余りの先頭LENbitだけである
    //    2/piの値の配列が大きくても1回の呼び出しで使用するのはその一部分に限られる
    //
    //  echo lm=32767;lw=9;default(realprecision,floor(lm*0.30103)+200);pi2=Pi/2;twopi=2/Pi;ln2=log(2);eval("hex(s)={my(v,h,i,c);v=Vecsmall(s);h=0;for(i=1,#v,c=v[i];if(c!=95,h=(h<<4)+if(48<=c&&c<=57,c-48,65<=c&&c<=70,c-55,97<=c&&c<=102,c-87,error)));h}");p=eval("twopi/2^(31*3)");a=vector((3+(lm+600)\31)\10*10,i,p=p*eval("2^31");w=floor(p);p=frac(p);printf("%s0x%08x,%s",if(i%10==1,"      ",""),w,if(i%10==0,"\n"," "));w);for(ee=0,lm,xx=hex("80000000000000000000000");tx=eval("xx/2^(91-ee)");tk=bitand(tx\pi2,3);ty=tx%pi2;yy=sum(i=1,lw,shift(a[ee\31+i],31*(lw-i)));ay=frac(xx*yy\eval("2^31")/eval("2^(31*(lw-1)-ee%31)"))*4;ak=floor(ay);ay=frac(ay)*pi2;dist=if(tk!=ak,-999,-log(abs((ay-ty)/ty))/ln2);printf("      //  %6d  %023x  %d  %32.30f  %d  %32.30f  %6.2f  %s%c",ee,xx,tk,ty,ak,ay,dist,if(eval("dist<96"),"ERROR","OK"),10)) | gp -q | grep "ERROR"
    //  エラーなし
    //  echo lm=32767;lw=9;default(realprecision,floor(lm*0.30103)+200);pi2=Pi/2;twopi=2/Pi;ln2=log(2);eval("hex(s)={my(v,h,i,c);v=Vecsmall(s);h=0;for(i=1,#v,c=v[i];if(c!=95,h=(h<<4)+if(48<=c&&c<=57,c-48,65<=c&&c<=70,c-55,97<=c&&c<=102,c-87,error)));h}");p=eval("twopi/2^(31*3)");a=vector((3+(lm+600)\31)\10*10,i,p=p*eval("2^31");w=floor(p);p=frac(p);printf("%s0x%08x,%s",if(i%10==1,"      ",""),w,if(i%10==0,"\n"," "));w);for(ee=0,lm,xx=hex("fffffffffffffffffffffff");tx=eval("xx/2^(91-ee)");tk=bitand(tx\pi2,3);ty=tx%pi2;yy=sum(i=1,lw,shift(a[ee\31+i],31*(lw-i)));ay=frac(xx*yy\eval("2^31")/eval("2^(31*(lw-1)-ee%31)"))*4;ak=floor(ay);ay=frac(ay)*pi2;dist=if(tk!=ak,-999,-log(abs((ay-ty)/ty))/ln2);printf("      //  %6d  %023x  %d  %32.30f  %d  %32.30f  %6.2f  %s%c",ee,xx,tk,ty,ak,ay,dist,if(eval("dist<96"),"ERROR","OK"),10)) | gp -q | grep "ERROR"
    //  エラーなし
    //
    //2/piの値
    //  echo lm=32767;lw=9;default(realprecision,floor(lm*0.30103)+200);pi2=Pi/2;twopi=2/Pi;ln2=log(2);eval("hex(s)={my(v,h,i,c);v=Vecsmall(s);h=0;for(i=1,#v,c=v[i];if(c!=95,h=(h<<4)+if(48<=c&&c<=57,c-48,65<=c&&c<=70,c-55,97<=c&&c<=102,c-87,error)));h}");p=eval("twopi/2^(31*3)");a=vector((3+(lm+600)\31)\10*10,i,p=p*eval("2^31");w=floor(p);p=frac(p);printf("%s0x%08x,%s",if(i%10==1,"      ",""),w,if(i%10==0,"\n"," "));w);for(ee=0,lm,xx=hex("c90fdaa22168c234c4c6629");tx=eval("xx/2^(91-ee)");tk=bitand(tx\pi2,3);ty=tx%pi2;yy=sum(i=1,lw,shift(a[ee\31+i],31*(lw-i)));ay=frac(xx*yy\eval("2^31")/eval("2^(31*(lw-1)-ee%31)"))*4;ak=floor(ay);ay=frac(ay)*pi2;dist=if(tk!=ak,-999,-log(abs((ay-ty)/ty))/ln2);printf("      //  %6d  %023x  %d  %32.30f  %d  %32.30f  %6.2f  %s%c",ee,xx,tk,ty,ak,ay,dist,if(eval("dist<96"),"ERROR","OK"),10)) | gp -q > two_pi_array.out
    //  エラーなし
    //
    public int ieeerempi2 () {
      return this.ieeerempi2 (this);
    }  //efp.ieeerempi2()
    public int ieeerempi2 (EFP x) {
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        this.flg = xf;  //そのまま
        return 0;
      }
      //±0,±Inf,NaN以外
      int xe = x.epp;
      long xd = x.dvl;
      long xc = x.cvl;
      int o;
      long t;
      if ((o = xe + 1) < 0 || o == 0 && ((t = xd - 0xc90fdaa22168c234L) < 0L ||
                                         t == 0L && xc >>> 1 <= 0xc4c6629L >>> 1)) {  //|x|<=pi/4
        this.flg = xf;  //そのまま
        this.epp = xe;
        this.dvl = xd;
        this.cvl = xc;
        return 0;
      }
      if ((o = xe - 1) < 0 || o == 0 && ((t = xd - 0x96cbe3f9990e91a7L) < 0L ||
                                         t == 0L && xc >>> 1 <= 0x9394c9fL >>> 1)) {  //|x|<=3*pi/4
        if (xf >= 0) {
          this.inner ().sub (x, PI_2).outer ().sub (PI_2A);  //x-pi/2
          return 1;
        } else {
          this.inner ().iadd (x, PI_2).outer ().add (PI_2A);  //x+pi/2
          return 3;
        }
      }
      //以下はxe>=1
      //92bitの仮数部を30bit,31bit,31bitに3分割する
      long x0 = xd >>> -30;  //上位30bit
      long x1 = xd >>> 3 & 0x7fffffffL;  //中位31bit
      long x2 = (xd << 28 | xc >>> -28) & 0x7fffffffL;  //下位31bit
      //  perl optdiv.pl 32767 31
      //  x/31==x*16913>>>19 (0<=x<=34966) [32767*16913==554188271]
      o = xe * 16913 >>> 19;  //xe/31。xe<0は不可
      long y0 = TWO_PI_ARRAY[o    ];
      long y1 = TWO_PI_ARRAY[o + 1];
      long y2 = TWO_PI_ARRAY[o + 2];
      long y3 = TWO_PI_ARRAY[o + 3];
      long y4 = TWO_PI_ARRAY[o + 4];
      long y5 = TWO_PI_ARRAY[o + 5];
      long y6 = TWO_PI_ARRAY[o + 6];
      long y7 = TWO_PI_ARRAY[o + 7];
      long y8 = TWO_PI_ARRAY[o + 8];
      //xとyを掛けて62bit左詰め4要素にする
      //                             x0 x1 x2
      //  *        y0 y1 y2 y3 y4 y5 y6 y7 y8
      //  -----------------------------------
      //          |     |     |     |   x2*y8
      //          |     |     |     |x1*y8|
      //          |     |     |     |x2*y7|
      //          |     |     |   x0*y8   |
      //          |     |     |   x1*y7   |
      //          |     |     |   x2*y6   |
      //          |     |     |x0*y7|     |
      //          |     |     |x1*y6|     |
      //          |     |     |x2*y5|     |
      //          |     |   x0*y6   |     |
      //          |     |   x1*y5   |     |
      //          |     |   x2*y4   |     |
      //          |     |x0*y5|     |     |
      //          |     |x1*y4|     |     |
      //          |     |x2*y3|     |     |
      //          |   x0*y4   |     |     |
      //          |   x1*y3   |     |     |
      //          |   x2*y2   |     |     |
      //          |x0*y3|     |     |     |
      //          |x1*y2|     |     |     |
      //          |x2*y1|     |     |     |
      //        x0*y2   |     |     |     |
      //        x1*y1   |     |     |     |
      //        x2*y0   |     |     |     |
      //     x0*y1|     |     |     |     |
      //     x1*y0|     |     |     |     |
      //  x0*y0   |     |     |     |     |
      //  -----------------------------------
      //           z0    z1    z2    z3
      long z3 = (x2 * y8 >>> 31) + x1 * y8 + x2 * y7;  //x2*y8の下位は捨てる
      long z2 = (z3 >>> 31) + x0 * y8 + x1 * y7 + x2 * y6;
      z3 = (z3 & 0x7fffffffL) + (z2 << 33 >>> 2) << 2;
      z2 = (z2 >>> 31) + x0 * y7 + x1 * y6 + x2 * y5;
      long z1 = (z2 >>> 31) + x0 * y6 + x1 * y5 + x2 * y4;
      z2 = (z2 & 0x7fffffffL) + (z1 << 33 >>> 2) << 2;
      z1 = (z1 >>> 31) + x0 * y5 + x1 * y4 + x2 * y3;
      long z0 = (z1 >>> 31) + x0 * y4 + x1 * y3 + x2 * y2;
      z1 = (z1 & 0x7fffffffL) + (z0 << 33 >>> 2) << 2;
      z0 = (z0 >>> 31) + x0 * y3 + x1 * y2 + x2 * y1 + (x0 * y2 + x1 * y1 + x2 * y0 << 31) << 2;  //溢れは無視する。x0*y1+x1*y0とx0*y0は不要
      //248bit左詰めにする
      z0 |= z1 >>> -2;
      z1 = z1 << 2 | z2 >>> -4;
      z2 = z2 << 4 | z3 >>> -6;
      z3 <<= 6;
      //左にxe%31bitずらす
      o = xe - o * 31;  //xe%31
      if (o != 0) {
        z0 = z0 << o | z1 >>> -o;
        z1 = z1 << o | z2 >>> -o;
        z2 = z2 << o | z3 >>> -o;
        z3 <<= o;
      }
      //商の下位2bitを取り出す
      o = (int) (z0 >>> -2);
      if (xf < 0) {
        o = -o;
      }
      //商の下位2bitを押し出して小数点以下だけにする
      z0 = z0 << 2 | z1 >>> -2;
      z1 = z1 << 2 | z2 >>> -2;
      z2 = z2 << 2 | z3 >>> -2;
      z3 <<= 2;
      //余りの絶対値が0.5以上のときは商の絶対値を1増やして余りの絶対値を1減らす
      //  左端が0.5の位なので左端が1ならば符号を反転する
      if (z0 < 0L) {
        o = xf >= 0 ? o + 1 : o - 1;
        t = z3 = -z3;
        t |= z2 = t == 0L ? -z2 : ~z2;
        t |= z1 = t == 0L ? -z1 : ~z1;
        z0 = t == 0L ? -z0 : ~z0;  //左端が0になるとは限らない。100...のときは符号反転しても100...のまま
        xf ^= M;
      }
      o &= 3;
      //正規化する
      if (z0 < 0L) {
        xe = -1;  //-1
      } else if (z0 != 0L) {
        xe = Long.numberOfLeadingZeros (z0);  //1..63。左にシフトするbit数
        z0 = z0 << xe | z1 >>> -xe;
        z1 = z1 << xe | z2 >>> -xe;
        z2 = z2 << xe | z3 >>> -xe;
        z3 <<= xe;
        xe = ~xe;  //-1-xe。-2..-64。指数
      } else if (z1 < 0L) {
        xe = -65;  //-65。指数
        z0 = z1;
        z1 = z2;
        z2 = z3;
        z3 = 0L;
      } else if (z1 != 0L) {
        xe = Long.numberOfLeadingZeros (z1) + 64;  //65..127。左にシフトするbit数
        z0 = z1 << xe | z2 >>> -xe;
        z1 = z2 << xe | z3 >>> -xe;
        z2 = z3 << xe;
        z3 = 0L;
        xe = ~xe;  //-1-xe。-66..-128。指数
      } else if (z2 < 0L) {
        xe = -129;  //-129。指数
        z0 = z2;
        z1 = z3;
        z2 = 0L;
        z3 = 0L;
      } else if (z2 != 0L) {
        xe = Long.numberOfLeadingZeros (z2) + 128;  //129..191。左にシフトするbit数
        z0 = z2 << xe | z3 >>> -xe;
        z1 = z3 << xe;
        z2 = 0L;
        z3 = 0L;
        xe = ~xe;  //-1-xe。-130..-192。指数
      } else if (z3 != 0L) {
        xe = Long.numberOfLeadingZeros (z3) + 192;  //192..255。左にシフトするbit数
        z0 = z3 << xe;
        z1 = 0L;
        z2 = 0L;
        z3 = 0L;
        xe = ~xe;  //-1-xe。-193..-256。指数
      } else {
        this.flg = xf | Z;
        return o;
      }
      //丸めの処理
      this.ifinish (xf, xe, z0, z1, z2 | z3);
      //pi/2を掛ける
      this.mul (PI_2);
      //商の下位2bitを返す
      return o;
    }  //efp.ieeerempi2(EFP)

    //------------------------------------------------------------------------
    //x = x.inc ()
    //  x+=1
    //y = y.inc (x)
    //  y=x+1
    //  1を加える(インクリメント)
    //
    //  グラフ
    //    perl -e "use Graph;$g=new Graph();$g->grid();$g->func(sub{$_[0]+1});print$g"
    //    echo read("../misc/efp.gp");eval("inc(x)=x+1");graph(inc) | gp -q
    //    +---------+---------+---------+---------+---------+---------+--------***--------+
    //    |                                       |                          ***          |
    //    |                                       |                        ***            |
    //    |                                       |                      ***              |
    //    |                                       |                    ***                |
    //    +                                       +                  ***                  +
    //    |                                       |                ***                    |
    //    |                                       |              ***                      |
    //    |                                       |            ***                        |
    //    |                                       |          ***                          |
    //    +                                       +        ***                            +
    //    |                                       |      ***                              |
    //    |                                       |    ***                                |
    //    |                                       |  ***                                  |
    //    |                                       |***                                    |
    //    +                                      ***                                      +
    //    |                                    ***|                                       |
    //    |                                  ***  |                                       |
    //    |                                ***    |                                       |
    //    |                              ***      |                                       |
    //    +---------+---------+--------***--------+---------+---------+---------+---------+
    //    |                          ***          |                                       |
    //    |                        ***            |                                       |
    //    |                      ***              |                                       |
    //    |                    ***                |                                       |
    //    +                  ***                  +                                       +
    //    |                ***                    |                                       |
    //    |              ***                      |                                       |
    //    |            ***                        |                                       |
    //    |          ***                          |                                       |
    //    +        ***                            +                                       +
    //    |      ***                              |                                       |
    //    |    ***                                |                                       |
    //    |  ***                                  |                                       |
    //    |***                                    |                                       |
    //    **                                      +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //
    public final EFP inc () {
      return this.inc (this);
    }  //efp.inc()
    public final EFP inc (EFP x) {
      //return this.add (x, ONE);  //7.6ns
      //6.2ns
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        if (xf << 1 < 0) {  //±0
          this.flg = P;  //+1
          this.epp = 0;
          this.dvl = MSB;
          this.cvl = 0L;
        } else {  //±Inf,NaN
          this.flg = xf;
        }
        return this;
      }
      //±0,±Inf,NaN以外
      int xe = x.epp;
      if (xe < -LEN) {  //..-LEN-1。xの先頭がguard bitよりも右
        //絶対値は1の方が大きいのでxを右にシフトするがxの絶対値が小さすぎるので1になる
        epbFpsr |= EPB_FPSR_X2;  //不正確な結果
        this.flg = P;  //+1
        this.epp = 0;
        this.dvl = MSB;
        this.cvl = 0L;
        return this;
      }
      long xd = x.dvl;
      long xc = x.cvl;
      if (LEN < xe) {  //LEN+1..。1がguard bitよりも右
        //絶対値はxの方が大きいので1を右にシフトするが1の絶対値が小さすぎるのでxになる
        epbFpsr |= EPB_FPSR_X2;  //不正確な結果
        return this.finish (xf, xe, xd, xc, 0L);  //x
      }
      long xb = 0L;
      if (xe == 0) {  //0。xの最上位bitと1が重なる
        //絶対値はxの方が大きいか等しいが小数点の位置は同じ
        if (xf < 0) {  //-x
          //絶対値から1を引く
          xd -= MSB;
        } else {  //+x
          //絶対値に1を加える
          xb = xc << -1;
          xc = xd << -1 | xc >>> 1;
          xd = (xd >>> 1) + (MSB >>> 1);
          xe++;
        }
      } else if (0 < xe) {  //1..LEN
        //絶対値はxの方が大きいので1を右にシフトする
        if (xf < 0) {  //-x
          //絶対値から1を引く
          if (xe <= 63) {  //1..63。xの上位の2bit目以降と1が重なる
            xd -= MSB >>> xe;  //最上位bitが1なのでボローはなく0にもならない
          } else {  //64..LEN。xの下位またはguard bitと1が重なる
            if (xc >>> ~xe != 0L) {  //下位の引く位置から上が0ではない。下位だけで引ける
              xc -= MSB >>> xe;
            } else {  //下位の引く位置から上が0なのでボローが発生する
              xc |= MSB >> xe;  //下位の引く位置から上は-1になる
              xd--;  //ボローを上位から引く
            }
          }
        } else {  //+x
          //絶対値に1を加える
          if (xe <= 63) {  //1..63。xの上位と1が重なる
            if ((xd += MSB >>> xe) >>> ~xe == 0L) {  //絶対値に1を加えたら加えたbitから上がすべて0になって溢れた
              xb = xc << -1;
              xc = xd << -1 | xc >>> 1;
              xd = MSB | xd >>> 1;
              xe++;
            }
          } else {  //64..LEN。xの下位またはguard bitと1が重なる
            if ((xc += MSB >>> xe) >>> ~xe == 0L && ++xd == 0L) {  //絶対値に1を加えたら加えたbitから上がすべて0になって溢れた
              xb = xc << -1;
              xc = xc >>> 1;
              xd = MSB;
              xe++;
            }
          }
        }
      } else {  //-LEN..-1
        //絶対値は1の方が大きいのでxを右にシフトする
        if (-63 <= xe) {  //-63..-1。xの先頭が1の右隣から上位の最下位bitまで
          xb = xc << xe;
          xc = xd << xe | xc >>> -xe;
          xd >>>= -xe;
        } else if (-64 == xe) {  //-64。xの先頭が下位の最上位bit
          xb = xc;
          xc = xd;
          xd = 0L;
        } else {  //-LEN..-65。xの先頭が下位の上から2bit目からguard bitまで
          xb = xd << xe | xc >>> -xe;
          xc = xd >>> -xe;
          xd = 0L;
        }
        xe = 0;
        if (xf < 0) {  //-x
          //絶対値を1から引く
          if (xb != 0L) {
            xb = -xb;
            xc = -1L - xc;
            xd = MSB - 1L - xd;
          } else if (xc != 0L) {
            xc = -xc;
            xd = MSB - 1L - xd;
          } else {
            xd = MSB - xd;
          }
          xf ^= M;  //符号反転
        } else {  //+x
          //絶対値に1を加える
          xd |= MSB;
        }
      }
      //正規化する
      if (xd >= 0L) {
        if (xd != 0L) {
          int o = Long.numberOfLeadingZeros (xd);  //1..63。左にシフトするbit数
          xe -= o;
          xd = xd << o | xc >>> -o;
          xc = xc << o | xb >>> -o;
          xb <<= o;
        } else if (xc < 0L) {
          xe -= 64;
          xd = xc;
          xc = xb;
          xb = 0L;
        } else if (xc != 0L) {
          int o = 64 + Long.numberOfLeadingZeros (xc);  //65..127。左にシフトするbit数
          xe -= o;
          xd = xc << o | xb >>> -o;
          xc = xb << o;
          xb = 0L;
        } else if (xb < 0L) {
          xe -= 128;
          xd = xb;
          xc = 0L;
          xb = 0L;
        } else if (xb != 0L) {
          int o = 128 + Long.numberOfLeadingZeros (xb);  //129..191。左にシフトするbit数
          xe -= o;
          xd = xb << o;
          xc = 0L;
          xb = 0L;
        } else {
          this.flg = P | Z;  //-1+1=+0
          return this;
        }
      }
      return this.finish (xf, xe, xd, xc, xb);
    }  //efp.inc(EFP)

    //------------------------------------------------------------------------
    //b = x.iseven ()
    //  偶数の整数か
    //
    //  NaNは偶数ではない
    //  ±0,±Infは偶数
    //  ±0,±Inf,NaN以外は1の位のbitがないか1の位のbitが0ならば偶数
    //
    public boolean iseven () {
      int xf = this.flg;
      int xe = this.epp;
      return (xf << 1 != 0 ? xf << 3 >= 0 :  //±0,±Infは偶数。NaNは整数ではない
              xe < 0 ? false :  //整数部の1が小数点よりも右側にあるということは小数点以下が0ではないので整数ではない
              xe > LEN - 1 ? true : //1の位が小数部よりも右側にあるということは1の位が0なので偶数
              xe <= 63 ? this.dvl << xe == 0L && this.cvl == 0L : this.cvl << xe == 0L);  //1の位と小数点以下がすべて0ならば偶数
    }  //efp.iseven()

    //------------------------------------------------------------------------
    //b = x.isinf ()
    //  ±Infか
    //
    public boolean isinf () {
      return this.flg << 2 < 0;  //±Inf
    }  //efp.isinf()

    //------------------------------------------------------------------------
    //b = x.isint ()
    //  整数か
    //
    //  NaNは整数ではない
    //  ±0,±Infは整数
    //  ±0,±Inf,NaN以外は小数点よりも右側にセットされているbitがなければ整数
    //
    public boolean isint () {
      int xf = this.flg;
      int xe = this.epp;
      return (xf << 1 != 0 ? xf << 3 >= 0 :  //±0,±Infは整数。NaNは整数ではない
              xe < 0 ? false :  //整数部の1が小数点よりも右側にあるということは小数点以下が0ではないので整数ではない
              xe >= LEN - 1 ? true : //小数点が小数部よりも右側にあるので整数
              xe <= 63 ? this.dvl << 1 << xe == 0L && this.cvl == 0L : this.cvl << xe == 0L);  //小数点以下がすべて0ならば偶数
    }  //efp.isint()

    //------------------------------------------------------------------------
    //b = x.isnan ()
    //  NaNか
    //
    public boolean isnan () {
      return this.flg << 3 < 0;  //NaN
    }  //efp.isnan()

    //------------------------------------------------------------------------
    //b = x.isodd ()
    //  奇数の整数か
    //
    //  NaNは奇数ではない
    //  ±0,±Infは奇数ではない
    //  ±0,±Inf,NaN以外は1の位のbitが1ならば奇数
    //
    public boolean isodd () {
      int xf = this.flg;
      int xe = this.epp;
      return (xf << 1 != 0 ? false :  //±0,±Infは奇数ではない。NaNは整数ではない
              xe < 0 ? false :  //整数部の1が小数点よりも右側にあるということは小数点以下が0ではないので整数ではない
              xe > LEN - 1 ? false : //1の位が小数部よりも右側にあるということは1の位が0なので奇数ではない
              xe <= 63 ? this.dvl << xe == MSB && this.cvl == 0L : this.cvl << xe == MSB);  //1の位が1で小数点以下がすべて0ならば奇数
    }  //efp.isodd()

    //------------------------------------------------------------------------
    //b = x.isone ()
    //  +1か
    //
    public boolean isone () {
      return (this.flg == P &&
              this.epp == 0 &&
              this.dvl == MSB &&
              this.cvl == 0L);  //1
    }  //efp.isone()

    //------------------------------------------------------------------------
    //b = x.iszero ()
    //  ±0か
    //
    public boolean iszero () {
      return this.flg << 1 < 0;  //±0
    }  //efp.iszero()

    //------------------------------------------------------------------------
    //b = x.le (y)
    //  b=x<=y
    //  より小さいか等しいか
    //
    //  -Inf==-Inf<-x<-0==+0<+x<+Inf==+Inf
    //
    //  NaNの扱い
    //    どちらかがNaNのときはfalseを返す
    //
    public boolean le (EFP y) {
      int xf = this.flg;
      int yf = y.flg;
      if ((xf | yf) << 1 != 0) {  //どちらかが±0,±Inf,NaN
        return EFP_LE_TABLE[xf >>> 28] << (yf >>> 28 - 1) < 0;
      }
      //両方±0,±Inf,NaN以外
      if (xf != yf) {  //両方±0,±Inf,NaN以外で符号が違う
        return xf < yf;
      }
      //両方±0,±Inf,NaN以外で符号が同じ
      int s;
      long t;
      return (xf >= 0 ? 1 : -1) * ((s = this.epp - y.epp) != 0 ? s >= 0 ? 1 : -1 :
                                   (t = this.dvl - y.dvl) != 0L ? t >= 0L ? 1 : -1 :
                                   (t = (this.cvl >>> 1) - (y.cvl >>> 1)) != 0L ? t >= 0L ? 1 : -1 :
                                   0) <= 0;
    }  //efp.le(EFP)

    //------------------------------------------------------------------------
    //x = x.log ()
    //  x=log(x)
    //y = y.log (x)
    //  y=log(x)
    //  自然対数 natural logarithm
    //
    //  グラフ
    //    perl -e "use Graph;$g=new Graph();$g->grid();$g->func(sub{log($_[0])});print$g"
    //    echo read("../misc/efp.gp");graph(log) | gp -q
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                    ****
    //    |                                       |                             ********  |
    //    +                                       +                        ******         +
    //    |                                       |                   ******              |
    //    |                                       |               *****                   |
    //    |                                       |            ****                       |
    //    |                                       |          ***                          |
    //    +---------+---------+---------+---------+--------***--------+---------+---------+
    //    |                                       |      ***                              |
    //    |                                       |     **                                |
    //    |                                       |    **                                 |
    //    |                                       |   **                                  |
    //    +                                       +  **                                   +
    //    |                                       |  *                                    |
    //    |                                       | **                                    |
    //    |                                       | *                                     |
    //    |                                       |**                                     |
    //    +                                       +*                                      +
    //    |                                       |*                                      |
    //    |                                       |*                                      |
    //    |                                       |*                                      |
    //    |                                       |*                                      |
    //    +                                       **                                      +
    //    |                                       *                                       |
    //    |                                       *                                       |
    //    |                                       *                                       |
    //    |                                       *                                       |
    //    +---------+---------+---------+---------*---------+---------+---------+---------+
    //
    //  定義域
    //    0<x<=inf
    //
    //  値域
    //    -inf<=y<=inf
    //
    //  テイラー展開
    //    > coeff(sub(a=0,for n:=0:8 sum sub(x=a,df(log(1+x),x,n))/factorial(n)*(x-a)^n),x);
    //           - 1   1    - 1   1    - 1   1    - 1
    //    {0,1,------,---,------,---,------,---,------}
    //           2     3    4     5    6     7    8
    //    log(1+x)=sum[n=1..inf]{(-1)^(n+1)*x^n/n}
    //    1<xのときはlog(x)=-log(1/x)で計算する
    //
    //  テイラー展開2
    //    log(1+x)=sum[n=1..inf]{(-1)^(n+1)*x^n/n}
    //    xに-xを代入すると偶数次の項は係数が負のままで奇数次の項は係数が正から負に変わるので
    //    log(1-x)=sum[n=1..inf]{-x^n/n}
    //    > coeff(sub(a=0,for n:=0:8 sum sub(x=a,df(log(1-x),x,n))/factorial(n)*(x-a)^n),x);
    //            - 1    - 1    - 1    - 1    - 1    - 1    - 1
    //    {0,-1,------,------,------,------,------,------,------}
    //            2      3      4      5      6      7      8
    //    これらを引くと偶数次の項が消えて
    //    log(1+x)-log(1-x)=2*sum[k=0..inf]{x^(2*k+1)/(2*k+1)}
    //    すなわち
    //    log((1+x)/(1-x))=2*sum[k=0..inf]{x^(2*k+1)/(2*k+1)}
    //    > coeff(sub(a=0,for n:=0:14 sum sub(x=a,df(log((1+x)/(1-x)),x,n))/factorial(n)*(x-a)^n),x);
    //            2     2     2     2     2      2
    //    {0,2,0,---,0,---,0,---,0,---,0,----,0,----}
    //            3     5     7     9     11     13
    //    ここで
    //    u=(x-1)/(x+1)
    //    とおくと
    //    x=(1+u)/(1-u)
    //    であるから
    //    log(x)=2*sum[k=0..inf]{u^(2*k+1)/(2*k+1)}
    //    0<x<infのとき-1<u<1なので定義域のほぼ全域で収束する
    //    それでもxが1から離れると収束が遅い
    //    式からわかるように、log(x)のグラフと2*(x-1)/(x+1)のグラフは1付近の形がよく似ている
    //    perl -e "use Graph;$g=new Graph();$g->grid();$g->func(sub{my($x)=@_;2*($x-1)/($x+1)});print$g"
    //    +--------***--------+---------+---------+---------+---------+---------+---------+
    //    |     ****                              |                                       |
    //    |  ****                                 |                                       |
    //    ****                                    |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                 *******
    //    +                                       +                         *********     +
    //    |                                       |                    ******             |
    //    |                                       |                *****                  |
    //    |                                       |             ****                      |
    //    |                                       |          ****                         |
    //    +---------+---------+---------+---------+--------***--------+---------+---------+
    //    |                                       |      ***                              |
    //    |                                       |     **                                |
    //    |                                       |    **                                 |
    //    |                                       |   **                                  |
    //    +                                       +  **                                   +
    //    |                                       | **                                    |
    //    |                                       |**                                     |
    //    |                                       |*                                      |
    //    |                                       **                                      |
    //    +                                       *                                       +
    //    |                                      **                                       |
    //    |                                      *|                                       |
    //    |                                      *|                                       |
    //    |                                     **|                                       |
    //    +                                     * +                                       +
    //    |                                     * |                                       |
    //    |                                    ** |                                       |
    //    |                                    *  |                                       |
    //    |                                    *  |                                       |
    //    +---------+---------+---------+------*--+---------+---------+---------+---------+
    //    差を10倍してみる
    //    perl -e "use Graph;$g=new Graph();$g->grid();$g->func(sub{my($x)=@_;10*(2*($x-1)/($x+1)-log($x))});print$g"
    //    +---------+---------+---------+---------+-*-------+---------+---------+---------+
    //    |                                       | *                                     |
    //    |                                       | *                                     |
    //    |                                       | *                                     |
    //    |                                       | *                                     |
    //    +                                       + *                                     +
    //    |                                       | *                                     |
    //    |                                       | *                                     |
    //    |                                       | *                                     |
    //    |                                       | *                                     |
    //    +                                       + *                                     +
    //    |                                       | **                                    |
    //    |                                       |  *                                    |
    //    |                                       |  *                                    |
    //    |                                       |  *                                    |
    //    +                                       +  *                                    +
    //    |                                       |  **                                   |
    //    |                                       |   *                                   |
    //    |                                       |   **                                  |
    //    |                                       |    **                                 |
    //    +---------+---------+---------+---------+-----***********---+---------+---------+
    //    |                                       |               ******                  |
    //    |                                       |                    ****               |
    //    |                                       |                       ***             |
    //    |                                       |                         ****          |
    //    +                                       +                            ***        +
    //    |                                       |                              ****     |
    //    |                                       |                                 ***   |
    //    |                                       |                                   *** |
    //    |                                       |                                     ***
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //
    //  テイラー展開3
    //    浮動小数点数の特性を利用して指数部を分離する
    //    x=2^k*vのとき
    //    log(x)=log(2^k*v)
    //          =k*log(2)+log(v)
    //    sqrt(2)/2<=v<=sqrt(2)
    //    となるようにkを選ぶと
    //    2*sqrt(2)-3<=(v-1)/(v+1)<=3-2*sqrt(2)
    //    -0.17157...<=(v-1)/(v+1)<=0.17157...
    //    となる
    //    1/(3-2*sqrt(2))^2=33.97...であるから1項増やす毎に5bit以上増える
    //    多倍長の場合はxと同じ精度のlog(2)を他の方法で求めなければならない
    //    echo read("../misc/efp.gp");eval("f(n,x)={my(u=(x-1)/(x+1));2*sum(k=0,n,u^(2*k+1)/(2*k+1))}");for(n=0,30,printf("%4d",floor(closeness2(log,f(n,x),sqrt(2)/2,sqrt(2))))) | gp -q
    //       0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30
    //       6  12  18  23  28  34  39  44  49  55  60  65  70  76  81  86  91  96 101 107 112 117 122 127 132 137 143 148 153 158 163
    //
    //  連分数展開
    //    log(1+x)=x/(1+x/(2+x/(3+4*x/(4+4*x/(5+9*x/(6+9*x/(7+...
    //      echo eval("h(k)=if(k==1,1/2,bitand(k,1)==0,k/(k+1)/4,(k+1)/k/4)");eval("g(n,x,k)=h(k)*x/(1+if(k<n,g(n,x,k+1),0))");eval("f(n,x)=x/(1+if(n<1,0,g(n,x,1)))");for(n=0,10,print("    //      f(",n,",x)=",f(n,x))) | gp -q
    //      f(0,x)=x
    //      f(1,x)=2*x/(x + 2)
    //      f(2,x)=(x^2 + 6*x)/(4*x + 6)
    //      f(3,x)=(3*x^2 + 6*x)/(x^2 + 6*x + 6)
    //      f(4,x)=(x^3 + 21*x^2 + 30*x)/(9*x^2 + 36*x + 30)
    //      f(5,x)=(11*x^3 + 60*x^2 + 60*x)/(3*x^3 + 36*x^2 + 90*x + 60)
    //      f(6,x)=(3*x^4 + 140*x^3 + 510*x^2 + 420*x)/(48*x^3 + 360*x^2 + 720*x + 420)
    //      f(7,x)=(25*x^4 + 260*x^3 + 630*x^2 + 420*x)/(6*x^4 + 120*x^3 + 540*x^2 + 840*x + 420)
    //      f(8,x)=(6*x^5 + 505*x^4 + 3360*x^3 + 6510*x^2 + 3780*x)/(150*x^4 + 1800*x^3 + 6300*x^2 + 8400*x + 3780)
    //      f(9,x)=(137*x^5 + 2310*x^4 + 9870*x^3 + 15120*x^2 + 7560*x)/(30*x^5 + 900*x^4 + 6300*x^3 + 16800*x^2 + 18900*x + 7560)
    //      f(10,x)=(5*x^6 + 672*x^5 + 7035*x^4 + 23520*x^3 + 30870*x^2 + 13860*x)/(180*x^5 + 3150*x^4 + 16800*x^3 + 37800*x^2 + 37800*x + 13860)
    //      echo read("../misc/efp.gp");eval("log1p(x)=log(1+x)");eval("h(k)=if(k==1,1/2,k%2==0,k/(k+1)/4,(k+1)/k/4)");eval("g(n,x,k)=h(k)*x/(1+if(k<n,g(n,x,k+1),0))");eval("f(n,x)=x/(1+if(n<1,0,g(n,x,1)))");for(n=0,30,printf("%4d",floor(closeness2(log1p,f(n,x),sqrt(2)/2-1,sqrt(2)-1)))) | gp -q
    //       0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30
    //       2   6   9  13  16  20  23  27  31  34  38  41  45  48  52  55  59  62  66  70  73  77  80  84  87  91  94  98 101 105 108
    //
    //  チェビシェフ展開
    //    x=(1+u)/(1-u)
    //    u=(x-1)/(x+1)
    //    log((1+u)/(1-u))=2*sum[k=0..inf]{u^(2*k+1)/(2*k+1)}
    //    の係数を調整する
    //    sqrt(2)/2<=x<=sqrt(2)
    //    のとき
    //    2*sqrt(2)-3<=u<=3-2*sqrt(2)
    //    であるから
    //    echo read("../misc/efp.gp");eval("f(u)=log((1+u)/(1-u))");a=2*sqrt(2)-3;b=3-2*sqrt(2);for(k=0,30,printf("%4d",floor(closeness2(f,chebyshev(f,a,b,2*k+1),a,b)))) | gp -q
    //       0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30
    //       7  14  21  28  35  42  49  56  63  70  77  84  91  98 105 113 120 127 134 141 148 155 162 169 176 183 190 197 204 211 219
    //
    //  expm1を高速に計算できる場合
    //    組み込み関数を使ってlog(x)=log1p(x-1)の近似値y'を求める
    //    expm1を使ってx'-1=expm1(y')を正確に求める。これは正確なのでlog(x')=y'である
    //    log(x)=log(x'*(x/x'))
    //          =log(x')+log(x/x')
    //          =y'+log((x'+x-x')/x')
    //          =y'+log(1+(x-x')/x')
    //          =y'+log1p((x'-x)/x)
    //    (x-x')/xは小さいのでlog1p((x-x')/x')は速く収束する
    //
    //  AGM
    //    I(a,b)=int[0..pi/2]{dt/sqrt(a^2*cos(t)^2+b^2*sin(t)^2)}
    //    T(a,b)=2/pi*I(a,b)=1/M(a,b)
    //    M(a[0],b[0])=lim[n=inf]{a[n]}=lim[n=inf]{b[n]}
    //    a[n+1]=(a[n]+b[n])/2
    //    b[n+1]=sqrt(a[n]*b[n])
    //    abs(log(x)-[I(1,10^-n)-I(1,10^-n*x)])<n*10^(2-2*n)  (0<x<1)
    //    echo read("../misc/efp.gp");eval("fi(a,b)=intnum(t=0,Pi/2,1/sqrt(a^2*cos(t)^2+b^2*sin(t)^2))");eval("f(n,x)=fi(1,2^-n)-fi(1,2^-n*x)");printf("%.30f",f(100,2)/f(100,10)) | gp -q
    //    0.301029995663981195213738894724
    //    echo read("../misc/efp.gp");eval("g(a,b)=Pi/2/agm(a,b)");eval("f(n,x)=g(1,2^-n)-g(1,2^-n*x)");printf("%.30f",f(100,2)/f(100,10)) | gp -q
    //    0.301029995663981195213738894724
    //    perl -e "sub mm{my($a,$b)=@_;while(1){my$t=($a+$b)/2;$t<$a or last;$b=sqrt($a*$b);$a=$t}$a};sub ii{my($a,$b)=@_;atan2(1,1)*2/mm($a,$b)}sub ll{my($x,$n)=@_;ii(1,2**-$n)-ii(1,2**-$n*$x)}printf'    //    %14s  %22s  %22s  %22s%c','x','log(x)','ll(x,31)','abs(ll(x,31)-log(x))',10;for my$k(-10..10){my$x=10**$k;printf'    //    %14.14g  %22.16g  %22.16g  %22.16g%c',$x,log($x),ll($x,31),abs(log($x)-ll($x,31)),10}"
    //                 x                  log(x)                ll(x,31)    abs(ll(x,31)-log(x))
    //             1e-10      -23.02585092994046      -23.02585092994045   3.552713678800501e-15
    //             1e-09      -20.72326583694641       -20.7232658369464   7.105427357601002e-15
    //             1e-08      -18.42068074395237      -18.42068074395237                       0
    //             1e-07      -16.11809565095832      -16.11809565095832   3.552713678800501e-15
    //             1e-06      -13.81551055796427      -13.81551055796427                       0
    //             1e-05      -11.51292546497023      -11.51292546497024   8.881784197001252e-15
    //            0.0001      -9.210340371976182       -9.21034037197618    1.77635683940025e-15
    //             0.001      -6.907755278982137      -6.907755278982144   7.105427357601002e-15
    //              0.01      -4.605170185988091      -4.605170185988086   4.440892098500626e-15
    //               0.1      -2.302585092994045       -2.30258509299405   4.884981308350689e-15
    //                 1                       0                       0                       0
    //                10       2.302585092994046       2.302585092994047   8.881784197001252e-16
    //               100       4.605170185988092       4.605170185988079   1.243449787580175e-14
    //              1000       6.907755278982137       6.907755278981323   8.135714324453147e-13
    //             10000       9.210340371976184       9.210340371907533   6.865086277230148e-11
    //            100000       11.51292546497023       11.51292545935356   5.616673348640688e-09
    //           1000000       13.81551055796427       13.81551012112039   4.368438872859315e-07
    //          10000000       16.11809565095832       16.11806444854419   3.120241413512304e-05
    //         100000000       18.42068074395237       18.41880659707298    0.001874146879391247
    //        1000000000       20.72326583694641        20.6532968557838     0.06996898116260653
    //       10000000000       23.02585092994046       21.30306063168329       1.722790298257163
    //    1<xのときはlog(x)=-log(1/x)で計算する
    //    収束は速いがsqrtが必要なので桁数が少ないときは効率が悪い
    //
    public final EFP log () {
      return this.log (this);
    }  //efp.log()
    public final EFP log (EFP x) {
      int xf = x.flg;
      if (xf != 0) {  //-x,±0,±Inf,NaN
        if (xf << 3 < 0) {  //NaN
          this.flg = N;  //log(NaN)=NaN
        } else if (xf << 1 < 0) {  //±0
          epbFpsr |= EPB_FPSR_DZ;
          epbExceptionOperandExponent = xf & M;
          epbExceptionOperandMantissa = 0x0000000000000000L;
          this.flg = M | I;  //log(±0)=-Inf
        } else if (xf >= 0) {  //+Inf
          this.flg = P | I;  //log(+Inf)=+Inf
        } else {  //-x,-Inf
          epbFpsr |= EPB_FPSR_OE;
          if (xf << 2 < 0) {  //log(-Inf)=NaN
            epbExceptionOperandExponent = M | 0x7fff << 16;
            epbExceptionOperandMantissa = 0x0000000000000000L;
          } else {  //log(-x)=NaN
            epbExceptionOperandExponent = M | 0x3fff + x.epp << 16;
            epbExceptionOperandMantissa = x.dvl;
          }
          this.flg = N;  //log(-x)=NaN, log(-Inf)=NaN
        }
        return this;
      }
      //-x,±0,±Inf,NaN以外
      if (x.epp == 0 && x.dvl == MSB && x.cvl == 0L) {  //+1
        this.flg = epbRoundingMode == EPB_MODE_RM ? M | Z : P | Z;  //log(1)=±0。RMのときだけ-0
        return this;
      }
      //-x,±0,+1,±Inf,NaN以外
      this.inner ();
      if (true) {
        //1の近くだけlog1p()を使う
        if ((x.epp == -1 && x.dvl >>> 32 == 0xffffffff00000000L >>> 32) ||  //1-2^32<=x<1
            (x.epp == 0 && x.dvl >>> 31 == 0x8000000000000000L >>> 31)) {  //1<=x<1+2^-32
          //return this.inner ().dec (x).outer ().log1p ();
          //log(1+x)=x-x^2/2+x^3/3
          EFP t = new EFP ().dec (x);
          return this.cub (t).div3 ().sub (new EFP ().squ (t).div2 ()).outer ().add (t);
        }
      }
      epbFpsr |= EPB_FPSR_X2;  //不正確な結果
      EFP v = new EFP (x);
      v.epp = v.dvl >= 0xb504f333f9de6484L ? -1 : 0;  //SQRT2
      int k = x.epp - v.epp;  //x=2^k*v, sqrt(2)/2<=v<=sqrt(2)
      if (true) {  //チェビシェフ展開。[90] 420ns
        EFP u = new EFP ().dec (v).div (v.inc ());  //u=(v-1)/(v+1)
        v.isqu (u);  //u^2
        /*
        this.imul (LOG_C25, v)
          .iadd (LOG_C23).imul (v)
            .iadd (LOG_C21).imul (v)
              .iadd (LOG_C19).imul (v)
                .iadd (LOG_C17).imul (v)
                  .iadd (LOG_C15).imul (v)
                    .iadd (LOG_C13).imul (v)
                      .iadd (LOG_C11).imul (v)
                        .iadd (LOG_C9).imul (v)
                          .iadd (LOG_C7).imul (v)
                            .iadd (LOG_C5).imul (v)
                              .iadd (LOG_C3).imul (v)
                                .iadd (LOG_C1).imul (u)
                                  .iadd (v.muli (LOG_2, k)).iadd (v.muli (LOG_2A, k));  //log(x)=log(2^k*v)=k*log(2)+log(v)
         */
        this.imul (LOG_C27, v)
          .iadd (LOG_C25).imul (v)
            .iadd (LOG_C23).imul (v)
              .iadd (LOG_C21).imul (v)
                .iadd (LOG_C19).imul (v)
                  .iadd (LOG_C17).imul (v)
                    .iadd (LOG_C15).imul (v)
                      .iadd (LOG_C13).imul (v)
                        .iadd (LOG_C11).imul (v)
                          .iadd (LOG_C9).imul (v)
                            .iadd (LOG_C7).imul (v)
                              .iadd (LOG_C5).imul (v)
                                .iadd (LOG_C3).imul (v)
                                  .iadd (LOG_C1).imul (u)
                                    .iadd (v.muli (LOG_2, k)).iadd (v.muli (LOG_2A, k));  //log(x)=log(2^k*v)=k*log(2)+log(v)
      } else {  //expm1を使う。[89] 520ns
        EFP vv1 = new EFP ().dec (v);
        if (vv1.flg << 1 < 0) {  //log(2^k*1)
          this.muli (LOG_2, k);  //log(2^k)=k*log(2)
        } else {
          EFP yy = ZERO;
          if (-1023 < vv1.epp) {
            //  Math.log1p(double)を使ってlog(v)の近似値y'を求める
            long s = Double.doubleToLongBits (Math.log1p (Double.longBitsToDouble ((long) (vv1.flg | 1023 + vv1.epp << 20) << 32 | vv1.dvl << 1 >>> 12)));
            if (s != 0L) {
              int sh = (int) (s >>> 32);
              yy = new EFP (sh & M, (sh >>> 20 & 2047) - 1023, MSB | s << 12 >>> 1, 0L);  //log(v)の近似値y'
            }
          }
          //  expm1を使ってlog(v')=y'を満たすv'を求める
          vv1.expm1 (yy);  //v'-1=expm1(y')
          //  log(v)=log(v')+log1p((v-v')/v')を使ってlog(v)を計算する
          //  (v-v')/v'は小さいので1次の項だけ加える
          v.dec ().sub (vv1);  //(v-1)-(v'-1)=v-v'
          this.rcp (vv1.inc ()).imul (v).iadd (yy)  //y'+(v-v')/v'≒log(v')+log1p((v-v')/v')=log(v)
            .iadd (v.muli (LOG_2, k)).iadd (v.muli (LOG_2A, k));  //log(x)=log(2^k*v)=k*log(2)+log(v)
        }
      }
      return outer ().finish ();
    }  //efp.log(EFP)

    //------------------------------------------------------------------------
    //x = x.log10 ()
    //  x=log10(x)
    //y = y.log10 (x)
    //  y=log10(x)
    //  常用対数 common logarithm
    //
    //  グラフ
    //    perl -e "use Graph;$g=new Graph();$g->grid();$g->func(sub{log($_[0])/log(10)});print$g"
    //    echo read("../misc/efp.gp");eval("log10(x)=log(x)/log(10)");graph(log10) | gp -q
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                               *********
    //    |                                       |                   *************       |
    //    |                                       |            ********                   |
    //    +---------+---------+---------+---------+-------******------+---------+---------+
    //    |                                       |    ****                               |
    //    |                                       |  ***                                  |
    //    |                                       | **                                    |
    //    |                                       |**                                     |
    //    +                                       +*                                      +
    //    |                                       |*                                      |
    //    |                                       **                                      |
    //    |                                       *                                       |
    //    |                                       *                                       |
    //    +                                       *                                       +
    //    |                                       *                                       |
    //    |                                       *                                       |
    //    |                                       *                                       |
    //    |                                       *                                       |
    //    +                                       *                                       +
    //    |                                       *                                       |
    //    |                                       *                                       |
    //    |                                       *                                       |
    //    |                                       |                                       |
    //    +---------+---------+---------+---------*---------+---------+---------+---------+
    //
    //  対数関数との関係
    //    log10(x)=log(x)/log(10)
    //
    public final EFP log10 () {
      return this.log10 (this);
    }  //efp.log10()
    public final EFP log10 (EFP x) {
      //return this.log (x).div (LOG_10);  //log(x)/log(10) [90]
      int xf = x.flg;
      if (xf != 0) {  //-x,±0,±Inf,NaN
        if (xf << 3 < 0) {  //NaN
          this.flg = N;  //log10(NaN)=NaN
        } else if (xf << 1 < 0) {  //±0
          epbFpsr |= EPB_FPSR_DZ;
          epbExceptionOperandExponent = xf & M;
          epbExceptionOperandMantissa = 0x0000000000000000L;
          this.flg = M | I;  //log10(±0)=-Inf
        } else if (xf >= 0) {  //+Inf
          epbExceptionOperandExponent = 0x7fff << 16;
          epbExceptionOperandMantissa = 0x0000000000000000L;
          this.flg = P | I;  //log10(+Inf)=+Inf
        } else {  //-x,-Inf
          epbFpsr |= EPB_FPSR_OE;
          if (xf << 2 < 0) {  //-Inf
            epbExceptionOperandExponent = M | 0x7fff << 16;
            epbExceptionOperandMantissa = 0x0000000000000000L;
          } else {  //-x
            epbExceptionOperandExponent = M | 0x3fff + x.epp << 16;
            epbExceptionOperandMantissa = x.dvl;
          }
          this.flg = N;  //log10(-x)=NaN, log10(-Inf)=NaN
        }
        return this;
      }
      //-x,±0,±Inf,NaN以外
      int xe = x.epp;
      //log10(1)を特別扱いにする
      if (xe == 0 && x.dvl == MSB && x.cvl == 0L) {  //log10(1)
        this.flg = epbRoundingMode == EPB_MODE_RM ? M | Z : P | Z;  //log10(1)=±0。RMのときは-0,RN,RZ,RPのときは+0
        return this;
      }
      //log10(10^n)(n>0)を特別扱いにする
      if (3 <= xe && xe <= 129) {
        EFP t = ACCURATE_LOG10_BASE[xe];
        if (t != null && x.dvl == t.dvl && x.cvl == t.cvl) {
          //結果は正確だがMC68882に合わせて不正確な結果をセットしておく
          epbFpsr |= EPB_FPSR_X2;  //不正確な結果
          //  perl -e "for$e(0..129){$n=($e+1)*617>>11;if($e==int(log(10**$n)/log(2))){print$e,' ';}}"
          //  0 3 6 9 13 16 19 23 26 29 33 36 39 43 46 49 53 56 59 63 66 69 73 76 79 83 86 89 93 96 99 102 106 109 112 116 119 122 126 129 
          return this.seti ((xe + 1) * 617 >> 11);
        }
      }
      //-x,±0,10^n,±Inf,NaN以外
      this.inner ();
      epbFpsr |= EPB_FPSR_X2;  //不正確な結果
      EFP v = new EFP (x);
      v.epp = v.dvl >= 0xb504f333f9de6484L ? -1 : 0;  //SQRT2
      int k = x.epp - v.epp;  //x=2^k*v, sqrt(2)/2<=v<=sqrt(2)
      EFP u = new EFP ().dec (v).div (v.inc ());  //u=(v-1)/(v+1)
      v.isqu (u);  //u^2
      this.imul (LOG10_C27, v)
        .iadd (LOG10_C25).imul (v)
          .iadd (LOG10_C23).imul (v)
            .iadd (LOG10_C21).imul (v)
              .iadd (LOG10_C19).imul (v)
                .iadd (LOG10_C17).imul (v)
                  .iadd (LOG10_C15).imul (v)
                    .iadd (LOG10_C13).imul (v)
                      .iadd (LOG10_C11).imul (v)
                        .iadd (LOG10_C9).imul (v)
                          .iadd (LOG10_C7).imul (v)
                            .iadd (LOG10_C5).imul (v)
                              .iadd (LOG10_C3).imul (v)
                                .iadd (LOG10_C1).imul (u)
                                  .iadd (u.muli (LOG10_2, k));
      u.muli (LOG10_2A, k);
      return this.outer ().add (u);  //log10(x)=log10(2^k*v)=k*log10(2)+log(v) [91]
    }  //efp.log10()

    //------------------------------------------------------------------------
    //x = x.log1p ()
    //  x=log(1+x)
    //y = y.log1p (x)
    //  y=log(1+x)
    //  1に近い数の自然対数 natural logarithm of number being close to 1
    //
    //  グラフ
    //    perl -e "use Graph;$g=new Graph();$g->grid();$g->func(sub{log(1+$_[0])});print$g"
    //    echo read("../misc/efp.gp");eval("log1p(x)=log(1+x)");graph(log1p) | gp -q
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                  ******
    //    |                                       |                          *********    |
    //    |                                       |                   ********            |
    //    +                                       +              ******                   +
    //    |                                       |         ******                        |
    //    |                                       |     *****                             |
    //    |                                       |  ****                                 |
    //    |                                       |***                                    |
    //    +---------+---------+---------+--------***--------+---------+---------+---------+
    //    |                                    ***|                                       |
    //    |                                   **  |                                       |
    //    |                                  **   |                                       |
    //    |                                 **    |                                       |
    //    +                                **     +                                       +
    //    |                                *      |                                       |
    //    |                               **      |                                       |
    //    |                               *       |                                       |
    //    |                              **       |                                       |
    //    +                              *        +                                       +
    //    |                              *        |                                       |
    //    |                              *        |                                       |
    //    |                              *        |                                       |
    //    |                              *        |                                       |
    //    +                             **        +                                       +
    //    |                             *         |                                       |
    //    |                             *         |                                       |
    //    |                             *         |                                       |
    //    |                             *         |                                       |
    //    +---------+---------+---------*---------+---------+---------+---------+---------+
    //
    //  メモ
    //    log1p(x)の存在意義は1に極端に近い値の対数をlog(x)よりも正確に求められることだが、
    //    これは変数xに1に極端に近い値が入っているときlog(x)よりもlog1p(x-1)の方が正確な結果を返すという意味ではない
    //    例えば有効桁数が10桁のときxに1.000000001111111111を代入しようとするとxの値は1.000000001になってしまう
    //    x-1で桁落ちした引数をlog1pに与えたところで結果の精度が高くなるわけがない
    //    1に極端に近い値を経由せずにlog1p(1.111111111e-9)を計算すれば正確な結果が得られる
    //
    //  テイラー展開
    //    log(1+x)=sum[n=1..inf]{(-1)^(n+1)*x^n/n}
    //
    //  チェビシェフ展開
    //    sqrt(2)/2-1<=x<=sqrt(2)-1
    //    のとき
    //    u=x/(x+2)
    //    x=2*u/(1-u)
    //    とおくと
    //    2*sqrt(2)-3<=u<=3-2*sqrt(2)
    //    log(x)のときと同じ多項式を使う
    //
    //  メモ
    //    log1p(-0)=-0,log1p(+0)=+0に注意する
    //
    public final EFP log1p () {
      return this.log1p (this);
    }  //efp.log1p()
    public final EFP log1p (EFP x) {
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        if (xf << 3 < 0) {  //NaN
          this.flg = N;  //log1p(NaN)=NaN
        } else if (xf << 1 < 0) {  //±0
          this.flg = xf;  //log1p(±0)=±0
        } else if (xf >= 0) {  //+Inf
          this.flg = P | I;  //log1p(+Inf)=+Inf
        } else {  //-Inf
          epbFpsr |= EPB_FPSR_OE;
          epbExceptionOperandExponent = M | 0x7fff << 16;
          epbExceptionOperandMantissa = 0x0000000000000000L;
          this.flg = N;  //log1p(-Inf)=NaN
        }
        return this;
      }
      //±0,±Inf,NaN以外
      if (xf < 0) {  //x<0
        if (x.epp == 0 && x.dvl == MSB && x.cvl == 0L) {  //x==-1
          epbFpsr |= EPB_FPSR_DZ;  //MC68882はlog1p(-1)でDZをセットする
          epbExceptionOperandExponent = M | 0x3fff << 16;
          epbExceptionOperandMantissa = 0x8000000000000000L;
          this.flg = M | I;  //log1p(-1)=-Inf
          return this;
        } else if (x.epp >= 0) {  //x<-1
          epbFpsr |= EPB_FPSR_OE;
          epbExceptionOperandExponent = M | 0x3fff + x.epp << 16;
          epbExceptionOperandMantissa = x.dvl;
          this.flg = N;  //log1p(x<-1)=NaN
          return this;
        }
      }
      epbFpsr |= EPB_FPSR_X2;  //不正確な結果
      //if (x.epp < -2 || (x.epp == -2 && x.dvl <= (xf < 0 ? 0x95f619980c4336f7L : 0xd413cccfe7799211L))) {  //sqrt(2)/2-1<=x<=sqrt(2)-1
      if (LOG1P_A.le (x) && x.le (LOG1P_B)) {  //sqrt(2)/2-1<=x<=sqrt(2)-1
        int savedFpsr = epbFpsr;
        this.inner ();
        if (this == x) {
          x = new EFP (x);
        }
        EFP u = new EFP ().iadd (x, TWO).rcpdiv (x);  //u=x/(x+2)
        EFP v = new EFP ().isqu (u);  //u^2
        /*
        return this.imul (LOG_C25, v)
          .iadd (LOG_C23).imul (v)
            .iadd (LOG_C21).imul (v)
              .iadd (LOG_C19).imul (v)
                .iadd (LOG_C17).imul (v)
                  .iadd (LOG_C15).imul (v)
                    .iadd (LOG_C13).imul (v)
                      .iadd (LOG_C11).imul (v)
                        .iadd (LOG_C9).imul (v)
                          .iadd (LOG_C7).imul (v)
                            .iadd (LOG_C5).imul (v)
                              .iadd (LOG_C3).imul (v)
                                .iadd (LOG_C1).outer ().mul (u);
         */
        this.imul (LOG_C27, v)
          .iadd (LOG_C25).imul (v)
            .iadd (LOG_C23).imul (v)
              .iadd (LOG_C21).imul (v)
                .iadd (LOG_C19).imul (v)
                  .iadd (LOG_C17).imul (v)
                    .iadd (LOG_C15).imul (v)
                      .iadd (LOG_C13).imul (v)
                        .iadd (LOG_C11).imul (v)
                          .iadd (LOG_C9).imul (v)
                            .iadd (LOG_C7).imul (v)
                              .iadd (LOG_C5).imul (v)
                                .iadd (LOG_C3).imul (v)
                                  .iadd (LOG_C1).outer ().mul (u);
        return this.originLowerLower (x).correctUnderflow (savedFpsr);
      }
      return this.inner ().inc (x).outer ().log ();  //log(1+x)
    }  //efp.log1p()

    //------------------------------------------------------------------------
    //x = x.log2 ()
    //  x=log2(x)
    //y = y.log2 (x)
    //  y=log2(x)
    //  二進対数 binary logarithm
    //
    //  グラフ
    //    perl -e "use Graph;$g=new Graph();$g->grid();$g->func(sub{log($_[0])/log(2)});print$g"
    //    echo read("../misc/efp.gp");eval("log2(x)=log(x)/log(2)");graph(log2) | gp -q
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                    ****
    //    |                                       |                               ******  |
    //    |                                       |                           *****       |
    //    |                                       |                        ****           |
    //    |                                       |                    *****              |
    //    +                                       +                  ***                  +
    //    |                                       |               ****                    |
    //    |                                       |             ***                       |
    //    |                                       |           ***                         |
    //    |                                       |          **                           |
    //    +---------+---------+---------+---------+--------***--------+---------+---------+
    //    |                                       |       **                              |
    //    |                                       |      **                               |
    //    |                                       |     **                                |
    //    |                                       |    **                                 |
    //    +                                       +    *                                  +
    //    |                                       |   **                                  |
    //    |                                       |   *                                   |
    //    |                                       |  **                                   |
    //    |                                       |  *                                    |
    //    +                                       + **                                    +
    //    |                                       | *                                     |
    //    |                                       | *                                     |
    //    |                                       | *                                     |
    //    |                                       |**                                     |
    //    +                                       +*                                      +
    //    |                                       |*                                      |
    //    |                                       |*                                      |
    //    |                                       |*                                      |
    //    |                                       |*                                      |
    //    +---------+---------+---------+---------+*--------+---------+---------+---------+
    //
    //  対数関数との関係
    //    log2(x)=log(x)/log(2)
    //
    //  チェビシェフ展開
    //    指数部を分離する
    //      log2(x)=log2(2^k*v)=k+log2(v)
    //      1<=v<2
    //    定義域を0に近付ける
    //      -(1-t)/(1+t)=(2-t)/(2+t)をtについて解くとt=sqrt(2)
    //      u=(v-sqrt(2))/(v+sqrt(2))
    //      2*sqrt(2)-3<=u<3-2*sqrt(2)
    //      v=sqrt(2)*(1+u)/(1-u)
    //      log2(v)=log2(sqrt(2)*(1+u)/(1-u))
    //    perl -e "use Graph;$g=new Graph();$g->grid();$g->func(sub{my($u)=@_;log(sqrt(2)*(1+$u)/(1-$u))/log(2)});print$g"
    //    +---------+---------+---------+---------+-------*-+---------+---------+---------+
    //    |                                       |       *                               |
    //    |                                       |       *                               |
    //    |                                       |      **                               |
    //    |                                       |      *                                |
    //    +                                       +      *                                +
    //    |                                       |     **                                |
    //    |                                       |     *                                 |
    //    |                                       |     *                                 |
    //    |                                       |    **                                 |
    //    +                                       +    *                                  +
    //    |                                       |   **                                  |
    //    |                                       |  **                                   |
    //    |                                       |  *                                    |
    //    |                                       | **                                    |
    //    +                                       +**                                     +
    //    |                                       |*                                      |
    //    |                                       **                                      |
    //    |                                      **                                       |
    //    |                                      *|                                       |
    //    +---------+---------+---------+-------**+---------+---------+---------+---------+
    //    |                                    ** |                                       |
    //    |                                    *  |                                       |
    //    |                                   **  |                                       |
    //    |                                  **   |                                       |
    //    +                                  *    +                                       +
    //    |                                 **    |                                       |
    //    |                                 *     |                                       |
    //    |                                 *     |                                       |
    //    |                                **     |                                       |
    //    +                                *      +                                       +
    //    |                                *      |                                       |
    //    |                               **      |                                       |
    //    |                               *       |                                       |
    //    |                               *       |                                       |
    //    +                               *       +                                       +
    //    |                              **       |                                       |
    //    |                              *        |                                       |
    //    |                              *        |                                       |
    //    |                              *        |                                       |
    //    +---------+---------+---------+*--------+---------+---------+---------+---------+
    //    奇関数にするためlog2(v)-1/2をチェビシェフ展開する
    //    echo read("../misc/efp.gp");eval("f(u)=log(sqrt(2)*(1+u)/(1-u))/log(2)-1/2");a=2*sqrt(2)-3;b=3-2*sqrt(2);forstep(n=1,31,2,printf("%4d",floor(closeness(f,chebyshev(f,a,b,n),a,b,10000)))); | gp -q
    //       1   3   5   7   9  11  13  15  17  19  21  23  25  27  29  31
    //       7  14  21  28  35  42  49  56  63  70  77  84  91  98 105 113
    //
    public final EFP log2 () {
      return this.log2 (this);
    }  //efp.log2()
    public final EFP log2 (EFP x) {
      //return this.log (x).div (LOG_2);  //log(x)/log(2)
      int xf = x.flg;
      if (xf != 0) {  //-x,±0,±Inf,NaN
        if (xf << 3 < 0) {  //NaN
          this.flg = N;  //log2(NaN)=NaN
        } else if (xf << 1 < 0) {  //±0
          epbFpsr |= EPB_FPSR_DZ;
          epbExceptionOperandExponent = xf & M;
          epbExceptionOperandMantissa = 0x0000000000000000L;
          this.flg = M | I;  //log2(±0)=-Inf
        } else if (xf >= 0) {  //+Inf
          this.flg = P | I;  //log2(+Inf)=+Inf
        } else {  //-x,-Inf
          epbFpsr |= EPB_FPSR_OE;
          if (xf << 2 < 0) {  //-Inf
            epbExceptionOperandExponent = M | 0x7fff << 16;
            epbExceptionOperandMantissa = 0x0000000000000000L;
          } else {  //-x
            epbExceptionOperandExponent = M | 0x3fff + x.epp << 16;
            epbExceptionOperandMantissa = x.dvl;
          }
          this.flg = N;  //log2(-x)=NaN, log2(-Inf)=NaN
        }
        return this;
      }
      //-x,±0,±Inf,NaN以外
      //log2(2^n)を特別扱いにする
      if (x.dvl == MSB && x.cvl == 0L) {  //log2(2^n)
        if (x.epp == 0) {  //log2(1)
          this.flg = epbRoundingMode == EPB_MODE_RM ? M | Z : P | Z;  //log2(1)=±0。RMのときは-0,RN,RZ,RPのときは+0
        } else {  //log2(2^n)(n>0)
          //結果は正確だがMC68882に合わせて不正確な結果をセットしておく
          epbFpsr |= EPB_FPSR_X2;  //不正確な結果
          this.seti (x.epp);  //log2(2^n)=n
        }
        return this;
      }
      //-x,±0,2^n,±Inf,NaN以外
      this.inner ();
      epbFpsr |= EPB_FPSR_X2;  //不正確な結果
      EFP v = new EFP (x);
      v.epp = v.dvl >= 0xb504f333f9de6484L ? -1 : 0;  //SQRT2
      int k = x.epp - v.epp;  //x=2^k*v, sqrt(2)/2<=v<=sqrt(2)
      EFP u = new EFP ().dec (v).div (v.inc ());  //u=(v-1)/(v+1)
      v.isqu (u);  //u^2
      this.imul (LOG2_C27, v)
        .iadd (LOG2_C25).imul (v)
          .iadd (LOG2_C23).imul (v)
            .iadd (LOG2_C21).imul (v)
              .iadd (LOG2_C19).imul (v)
                .iadd (LOG2_C17).imul (v)
                  .iadd (LOG2_C15).imul (v)
                    .iadd (LOG2_C13).imul (v)
                      .iadd (LOG2_C11).imul (v)
                        .iadd (LOG2_C9).imul (v)
                          .iadd (LOG2_C7).imul (v)
                            .iadd (LOG2_C5).imul (v)
                              .iadd (LOG2_C3).imul (v)
                                .iadd (LOG2_C1).imul (u);
      u.seti (k);
      return this.outer ().add (u);  //log2(x)=log2(2^k*v)=k+log2(v)
    }  //efp.log2()

    //------------------------------------------------------------------------
    //x = x.lgamma ()
    //  x=log(Γ(x))
    //y = y.lgamma (x)
    //  y=log(Γ(x))
    //  ログガンマ関数
    //
    //  グラフ
    //    echo read("../misc/efp.gp");graph(lngamma) | gp -q
    //    +---------+---------+---------+---------*---------+---------+---------+---------+
    //    |                                       *                                       |
    //    |                                       *                                       |
    //    |                                       *                                       |
    //    |                                       *                                       |
    //    +                                       **                                      +
    //    |                                       |*                                      |
    //    |                                       |*                                      |
    //    |                                       |*                                      |
    //    |                                       |*                                      |
    //    +                                       +*                                      +
    //    |                                       |**                                    **
    //    |                                       | *                                   **|
    //    |                                       | *                                 *** |
    //    |                                       | **                              ***   |
    //    +                                       +  **                           ***     +
    //    |                                       |   *                         ***       |
    //    |                                       |   **                      ***         |
    //    |                                       |    ***                 ****           |
    //    |                                       |      ***            ****              |
    //    +---------+---------+---------+---------+--------*****---******-------+---------+
    //    |                                       |            *****                      |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //
    //  0<x<13のとき
    //    Γ(x)=Γ(x+1)/x
    //    log(Γ(x))=log(Γ(x+1))-log(x)
    //    で13<=xまで持っていく
    //    log(Γ(12+α))=log(Γ(13+α))-log(12+α)
    //    log(Γ(11+α))=log(Γ(12+α))-log(11+α)
    //                =log(Γ(13+α))-log(12+α)-log(11+α)
    //                =log(Γ(13+α))-log((12+α)*(11+α))
    //    log(Γ(10+α))=log(Γ(11+α))-log(10+α)
    //                =log(Γ(13+α))-log((12+α)*(11+α))-log(10+α)
    //                =log(Γ(13+α))-log((12+α)*(11+α)*(10+α))
    //                :
    //    すなわち
    //    d=1
    //    while x<13
    //      d*=x
    //      x+=1
    //    としてからlog(Γ(x))を計算してlog(Γ(x))-log(d)を返す
    //
    //  13<=xのとき
    //    log(Γ(x))=(x-1/2)*log(x)-x+log(2*π)/2+Σ[n=1..∞]{B(2*n)/(2*n*(2*n-1)*x^(2*n-1))]
    //
    public final EFP lgamma () {
      return this.lgamma (this);
    }  //efp.lgamma()
    public final EFP lgamma (EFP x) {
      int xf = x.flg;
      if (xf != 0) {  //-x,±0,±Inf,NaN
        this.flg = (xf == (P | Z) || xf == (P | I) ? P | I :  //lgamma(+0)=lgamma(+Inf)=+Inf
                    N);  //lgamma(NaN)=lgamma(-Inf)=lgamma(-x)=lgamma(-0)=NaN
        return this;
      }
      //+x
      this.inner ();
      x = new EFP (x);
      EFP d = null;
      if (x.lt (THIRTEEN)) {
        d = new EFP (ONE);
        do {
          d.mul (x);
          x.inc ();
        } while (x.lt (THIRTEEN));
      }
      EFP t = new EFP ().rcp (x);  //1/x
      EFP t2 = new EFP ().squ (t);  //1/x^2
      this.mul (LGAMMA_C14, t2)
        .add (LGAMMA_C13).mul (t2)
          .add (LGAMMA_C12).mul (t2)
            .add (LGAMMA_C11).mul (t2)
              .add (LGAMMA_C10).mul (t2)
                .add (LGAMMA_C9).mul (t2)
                  .add (LGAMMA_C8).mul (t2)
                    .add (LGAMMA_C7).mul (t2)
                      .add (LGAMMA_C6).mul (t2)
                        .add (LGAMMA_C5).mul (t2)
                          .add (LGAMMA_C4).mul (t2)
                            .add (LGAMMA_C3).mul (t2)
                              .add (LGAMMA_C2).mul (t2)
                                .add (LGAMMA_C1).mul (t)
                                  .add (LOGTWOPI_2).sub (x);  //-x+log(2*π)/2+Σ[n=1..14]{B(2*n)/(2*n*(2*n-1)*x^(2*n-1))]
      t.sub (x, ONE_2);  //x-1/2
      this.add (x.log ().mul (t));  //(x-1/2)*log(x)-x+log(2*π)/2+Σ[n=1..14]{B(2*n)/(2*n*(2*n-1)*x^(2*n-1))]
      if (d != null) {
        this.sub (d.log ());  //log(Γ(x))-log(d)
      }
      return this.outer ().finish ();
    }  //efp.lgamma(EFP)

    //------------------------------------------------------------------------
    //b = x.lt (y)
    //  b=x<y
    //  より小さいか
    //
    //  -Inf==-Inf<-x<-0==+0<+x<+Inf==+Inf
    //
    //  NaNの扱い
    //    どちらかがNaNのときはfalseを返す
    //
    public boolean lt (EFP y) {
      int xf = this.flg;
      int yf = y.flg;
      if ((xf | yf) << 1 != 0) {  //どちらかが±0,±Inf,NaN
        return EFP_LT_TABLE[xf >>> 28] << (yf >>> 28 - 1) < 0;
      }
      //両方±0,±Inf,NaN以外
      if (xf != yf) {  //両方±0,±Inf,NaN以外で符号が違う
        return xf < yf;
      }
      //両方±0,±Inf,NaN以外で符号が同じ
      int s;
      long t;
      return (xf >= 0 ? 1 : -1) * ((s = this.epp - y.epp) != 0 ? s >= 0 ? 1 : -1 :
                                   (t = this.dvl - y.dvl) != 0L ? t >= 0L ? 1 : -1 :
                                   (t = (this.cvl >>> 1) - (y.cvl >>> 1)) != 0L ? t >= 0L ? 1 : -1 :
                                   0) < 0;
    }  //efp.lt(EFP)

    //------------------------------------------------------------------------
    //x = x.max (y)
    //  x=max(x,y)
    //z = z.max (x, y)
    //  z=max(x,y)
    //  最大値
    //
    //  どちらかがNaNのときはNaN
    //  -0<+0とみなされる
    //
    public final EFP max (EFP y) {
      return this.max (this, y);
    }  //efp.max(EFP)
    public final EFP max (EFP x, EFP y) {
      if ((x.flg | y.flg) << 3 < 0) {  //どちらかがNaN
        this.flg = N;  //NaN
      } else if (x.compareTo (y) >= 0) {  //両方NaN以外でx>=y。cmpは-0>=+0なので不可
        this.flg = x.flg;  //x
        this.epp = x.epp;
        this.dvl = x.dvl;
        this.cvl = x.cvl;
      } else {  //両方NaN以外でx<y
        this.flg = y.flg;  //y
        this.epp = y.epp;
        this.dvl = y.dvl;
        this.cvl = y.cvl;
      }
      return this;
    }  //efp.max(EFP)

    //------------------------------------------------------------------------
    //x = x.min (y)
    //  x=min(x,y)
    //z = z.min (x, y)
    //  z=min(x,y)
    //  最小値
    //
    //  どちらかがNaNのときはNaN
    //  -0<+0とみなされる
    //
    public final EFP min (EFP y) {
      return this.min (this, y);
    }  //efp.min(EFP)
    public final EFP min (EFP x, EFP y) {
      if ((x.flg | y.flg) << 3 < 0) {  //どちらかがNaN
        this.flg = N;  //NaN
      } else if (x.compareTo (y) <= 0) {  //両方NaN以外でx<=y。cmpは+0<=-0なので不可
        this.flg = x.flg;  //x
        this.epp = x.epp;
        this.dvl = x.dvl;
        this.cvl = x.cvl;
      } else {  //両方NaN以外でx<y
        this.flg = y.flg;  //y
        this.epp = y.epp;
        this.dvl = y.dvl;
        this.cvl = y.cvl;
      }
      return this;
    }  //efp.min(EFP)

    //------------------------------------------------------------------------
    //x = x.mul (y)
    //  x*=y
    //z = z.mul (x, y)
    //  z=x*y
    //  乗算
    //
    //  (xn/xd)*(yn/yd)
    //    =(xn*yn)/(xd*yd)
    //
    //  分割統治法による多倍長乗算
    //    2分割
    //      (a*x+b)*(c*x+d) = a*c*x^2+(a*d+b*c)*x+b*d
    //                        (1)      (2) (3)    (4)
    //                      = a*c*(x^2+x)+b*d*(x+1)-(a-b)*(c-d)*x
    //                        (1)         (2)           (3)
    //        (3)の積は(a,b),(c,d)の大小関係によって加える場合と引く場合がある
    //      桁数を2倍にしたとき乗算のコストが3倍になる
    //      桁数n=2^kのときのコストは3^k=3^log2(n)=n^log2(3)≒n^1.585
    //    3分割
    //      (a*x^2+b*x+c)*(d*x^2+e*x+f) = a*d*x^4+(a*e+b*d)*x^3+(a*f+b*e+c*d)*x^2+(b*f+c*e)*x+c*f
    //                                    (1)      (2) (3)       (4) (5) (6)       (7) (8)    (9)
    //                                  = a*d*(x^4+x^3+x^2)+b*e*(x^3+x^2+x)+c*f*(x^2+x+1)-(a-b)*(d-e)*x^3-(a-c)*(d-f)*x^2-(b-c)*(e-f)*x
    //                                    (1)               (2)             (3)               (4)             (5)             (6)
    //        (4),(5),(6)の積は(a,b,c),(d,e,f)の大小関係によって加える場合と引く場合がある
    //      桁数を3倍にしたとき乗算のコストが6倍になる
    //      桁数n=3^kのときのコストは6^k=6^log3(n)=n^log3(6)≒n^1.631
    //    分割統治法による多倍長乗算では3分割よりも2分割の方が効率が良い
    //
    //    32bit,30bit,30bitに分割する場合
    //       x^6    x^5    x^4    x^3    x^2    x^1    x^0
    //      +---------------+-------------+-------------+
    //      |      a*d      |     c*f     |     c*f     |
    //      +---------------+-------------+-------------+
    //             +---------------+-------------+
    //             |      a*d      |     c*f     |
    //             +---------------+-------------+
    //                    +---------------+
    //                    |      a*d      |
    //                    +---------------+
    //               +-------------+-------------+
    //               |     b*e     |     b*e     |
    //               +-------------+-------------+
    //                      +-------------+
    //                      |     b*e     |
    //                      +-------------+
    //             +---------------+-------------+
    //             | -(a-b)*(d-e)  |-(b-c)*(e-f) |
    //             +---------------+-------------+
    //                    +---------------+
    //                    | -(a-c)*(d-f)  |
    //                    +---------------+
    //       x^6    x^5    x^4    x^3    x^2    x^1    x^0
    //
    public final EFP mul (EFP y) {
      int xf = this.flg;
      int yf = y.flg;
      {
        int o;
        if ((o = xf | yf) << 1 != 0) {  //どちらかが±0,±Inf,NaN
          if (o << 3 < 0) {  //どちらかがNaNのときNaN
            this.flg = N;
          } else if ((o &= (Z | I)) == (Z | I)) {  //±0*±InfのときNaN
            epbFpsr |= EPB_FPSR_OE;
            if (yf << 1 < 0) {  //±Inf*±0
              epbExceptionOperandExponent = yf & M;
              epbExceptionOperandMantissa = 0x0000000000000000L;
            } else {  //±0*±Inf
              epbExceptionOperandExponent = yf & M | 0x7fff << 16;
              epbExceptionOperandMantissa = 0x0000000000000000L;
            }
            this.flg = N;
          } else {  //両方±0,NaN以外でどちらかが±Infのとき±Inf、両方±Inf,NaN以外でどちらかが±0のとき±0
            this.flg = (xf ^ yf) & M | o;
          }
          return this;
        }
      }
      //符号
      int zf = xf ^ yf;  //符号が同じならばP、異なればM。ここでセットされるのはMだけ
      //指数部
      int ze = this.epp + y.epp;
      //以下はLEN<=92bitでなければならない
      //掛ける
      //  92bitの仮数部を32bit,30bit,30bitに3分割する
      //                                                                  111111111122222222223333333333444444444455555555556666
      //                                                        0123456789012345678901234567890123456789012345678901234567890123
      //                                                 x.dvl  HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLL
      //                                                 x.cvl  LLLLLLLLLLLLLLLLLLLLLLLLLLLL000000000000000000000000000000000000
      long xh = this.dvl;  //                               xh  HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLL
      long yh = y.dvl;
      long xl = (xh << -2 | this.cvl >>> 2) >>> -30;  //xh<<-2  LL00000000000000000000000000000000000000000000000000000000000000
      //                                             x.cvl>>>2  00LLLLLLLLLLLLLLLLLLLLLLLLLLLL0000000000000000000000000000000000
      //                                      xh<<-2|x.cvl>>>2  LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL0000000000000000000000000000000000
      //                                                    xl  0000000000000000000000000000000000LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
      long yl = (yh << -2 | y.cvl >>> 2) >>> -30;
      long xm = xh << 32 >>> -30;  //                   xh<<32  MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLL00000000000000000000000000000000
      //                                                    xm  0000000000000000000000000000000000MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
      long ym = yh << 32 >>> -30;
      xh >>>= 32;  //                                       xh  00000000000000000000000000000000HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
      yh >>>= 32;
      //           xh xm xl
      //  *        yh ym yl
      //  -----------------
      //              xl*yl
      //           xl*ym
      //           yl*xm
      //        xl*yh
      //        yl*xh
      //        xm*ym
      //     xm*yh
      //     ym*xh
      //  xh*yh
      //  -----------------
      //  zd    zc    zb
      long zb = xl * yl;  //60bit
      long zc = xl * yh + yl * xh + xm * ym;  //62bit*2+60bit
      long zd = xh * yh;  //64bit
      xl *= ym;  //xl*ym。60bit
      yl *= xm;  //yl*xm。60bit
      xm *= yh;  //xm*yh。62bit
      ym *= xh;  //ym*xh。62bit
      zb += (xl << -30 >>> 4) + (yl << -30 >>> 4);  //xl*ymの下位30bit<<30,yl*xmの下位30bit<<30。60bit*3
      zc += (xm << -30 >>> 4) + (ym << -30 >>> 4);  //xm*yhの下位30bit<<30,ym*xhの下位30bit<<30。62bit*2+60bit*3
      zc += (xl >>> 30) + (yl >>> 30) + (zb >>> -4);  //xl*ymの上位30bit,yl*xmの上位30bit,zbからのキャリー4bit。62bit*2+60bit*3+30bit*2+4bitで64bitに収まる
      zd += (xm >>> 30) + (ym >>> 30) + (zc >>> -4);  //xm*yhの上位32bit,ym*xhの上位32bit,zcからのキャリー4bit。積は92*2=184bitで64bit,60bit,60bitに収まる
      zb <<= 4;  //sticky bitにゴミが残っていると困るので使用済みのキャリーを押し出す
      zc <<= 4;  //使用済みのキャリーを押し出してzdとzcの隙間を詰める。zcの下位4bitに隙間ができるがsticky bitなのでzbを詰める必要はない
      //正規化する
      //  zdのMSBに隙間がないときは整数部が1+1=2bitになっているので指数部を1増やす
      if (zd < 0L) {
        ze++;
      } else {
        zd = zd << 1 | zc >>> -1;
        zc <<= 1;
      }
      return this.finish2 (zf, ze, zd, zc, zb);
    }  //efp.mul(EFP)
    public final EFP imul (EFP y) {
      int xf = this.flg;
      int yf = y.flg;
      {
        int o;
        if ((o = xf | yf) << 1 != 0) {  //どちらかが±0,±Inf,NaN
          if (o << 3 < 0) {  //どちらかがNaNのときNaN
            this.flg = N;
          } else if ((o &= (Z | I)) == (Z | I)) {  //±0*±InfのときNaN
            epbFpsr |= EPB_FPSR_OE;
            if (yf << 1 < 0) {  //±Inf*±0
              epbExceptionOperandExponent = yf & M;
              epbExceptionOperandMantissa = 0x0000000000000000L;
            } else {  //±0*±Inf
              epbExceptionOperandExponent = yf & M | 0x7fff << 16;
              epbExceptionOperandMantissa = 0x0000000000000000L;
            }
            this.flg = N;
          } else {  //両方±0,NaN以外でどちらかが±Infのとき±Inf、両方±Inf,NaN以外でどちらかが±0のとき±0
            this.flg = (xf ^ yf) & M | o;
          }
          return this;
        }
      }
      //符号
      int zf = xf ^ yf;  //符号が同じならばP、異なればM。ここでセットされるのはMだけ
      //指数部
      int ze = this.epp + y.epp;
      //以下はLEN<=92bitでなければならない
      //掛ける
      //  92bitの仮数部を32bit,30bit,30bitに3分割する
      //                                                                  111111111122222222223333333333444444444455555555556666
      //                                                        0123456789012345678901234567890123456789012345678901234567890123
      //                                                 x.dvl  HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLL
      //                                                 x.cvl  LLLLLLLLLLLLLLLLLLLLLLLLLLLL000000000000000000000000000000000000
      long xh = this.dvl;  //                               xh  HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLL
      long yh = y.dvl;
      long xl = (xh << -2 | this.cvl >>> 2) >>> -30;  //xh<<-2  LL00000000000000000000000000000000000000000000000000000000000000
      //                                             x.cvl>>>2  00LLLLLLLLLLLLLLLLLLLLLLLLLLLL0000000000000000000000000000000000
      //                                      xh<<-2|x.cvl>>>2  LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL0000000000000000000000000000000000
      //                                                    xl  0000000000000000000000000000000000LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
      long yl = (yh << -2 | y.cvl >>> 2) >>> -30;
      long xm = xh << 32 >>> -30;  //                   xh<<32  MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLL00000000000000000000000000000000
      //                                                    xm  0000000000000000000000000000000000MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
      long ym = yh << 32 >>> -30;
      xh >>>= 32;  //                                       xh  00000000000000000000000000000000HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
      yh >>>= 32;
      //           xh xm xl
      //  *        yh ym yl
      //  -----------------
      //              xl*yl
      //           xl*ym
      //           yl*xm
      //        xl*yh
      //        yl*xh
      //        xm*ym
      //     xm*yh
      //     ym*xh
      //  xh*yh
      //  -----------------
      //  zd    zc    zb
      long zb = xl * yl;  //60bit
      long zc = xl * yh + yl * xh + xm * ym;  //62bit*2+60bit
      long zd = xh * yh;  //64bit
      xl *= ym;  //xl*ym。60bit
      yl *= xm;  //yl*xm。60bit
      xm *= yh;  //xm*yh。62bit
      ym *= xh;  //ym*xh。62bit
      zb += (xl << -30 >>> 4) + (yl << -30 >>> 4);  //xl*ymの下位30bit<<30,yl*xmの下位30bit<<30。60bit*3
      zc += (xm << -30 >>> 4) + (ym << -30 >>> 4);  //xm*yhの下位30bit<<30,ym*xhの下位30bit<<30。62bit*2+60bit*3
      zc += (xl >>> 30) + (yl >>> 30) + (zb >>> -4);  //xl*ymの上位30bit,yl*xmの上位30bit,zbからのキャリー4bit。62bit*2+60bit*3+30bit*2+4bitで64bitに収まる
      zd += (xm >>> 30) + (ym >>> 30) + (zc >>> -4);  //xm*yhの上位32bit,ym*xhの上位32bit,zcからのキャリー4bit。積は92*2=184bitで64bit,60bit,60bitに収まる
      zb <<= 4;  //sticky bitにゴミが残っていると困るので使用済みのキャリーを押し出す
      zc <<= 4;  //使用済みのキャリーを押し出してzdとzcの隙間を詰める。zcの下位4bitに隙間ができるがsticky bitなのでzbを詰める必要はない
      //正規化する
      //  zdのMSBに隙間がないときは整数部が1+1=2bitになっているので指数部を1増やす
      if (zd < 0L) {
        ze++;
      } else {
        zd = zd << 1 | zc >>> -1;
        zc <<= 1;
      }
      return this.ifinish (zf, ze, zd, zc, zb);
    }  //efp.imul(EFP)
    public final EFP mul (EFP x, EFP y) {  //11.7
      int xf = x.flg;
      int yf = y.flg;
      {
        int o;
        if ((o = xf | yf) << 1 != 0) {  //どちらかが±0,±Inf,NaN
          if (o << 3 < 0) {  //どちらかがNaNのときNaN
            this.flg = N;
          } else if ((o &= (Z | I)) == (Z | I)) {  //±0*±InfのときNaN
            epbFpsr |= EPB_FPSR_OE;
            if (yf << 1 < 0) {  //±Inf*±0
              epbExceptionOperandExponent = yf & M;
              epbExceptionOperandMantissa = 0x0000000000000000L;
            } else {  //±0*±Inf
              epbExceptionOperandExponent = yf & M | 0x7fff << 16;
              epbExceptionOperandMantissa = 0x0000000000000000L;
            }
            this.flg = N;
          } else {  //両方±0,NaN以外でどちらかが±Infのとき±Inf、両方±Inf,NaN以外でどちらかが±0のとき±0
            this.flg = (xf ^ yf) & M | o;
          }
          return this;
        }
      }
      //符号
      int zf = xf ^ yf;  //符号が同じならばP、異なればM。ここでセットされるのはMだけ
      //指数部
      int ze = x.epp + y.epp;
      //以下はLEN<=92bitでなければならない
      //掛ける
      //  92bitの仮数部を32bit,30bit,30bitに3分割する
      //                                                                  111111111122222222223333333333444444444455555555556666
      //                                                        0123456789012345678901234567890123456789012345678901234567890123
      //                                                 x.dvl  HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLL
      //                                                 x.cvl  LLLLLLLLLLLLLLLLLLLLLLLLLLLL000000000000000000000000000000000000
      long xh = x.dvl;  //                                  xh  HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLL
      long yh = y.dvl;
      long xl = (xh << -2 | x.cvl >>> 2) >>> -30;  //   xh<<-2  LL00000000000000000000000000000000000000000000000000000000000000
      //                                             x.cvl>>>2  00LLLLLLLLLLLLLLLLLLLLLLLLLLLL0000000000000000000000000000000000
      //                                      xh<<-2|x.cvl>>>2  LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL0000000000000000000000000000000000
      //                                                    xl  0000000000000000000000000000000000LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
      long yl = (yh << -2 | y.cvl >>> 2) >>> -30;
      long xm = xh << 32 >>> -30;  //                   xh<<32  MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLL00000000000000000000000000000000
      //                                                    xm  0000000000000000000000000000000000MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
      long ym = yh << 32 >>> -30;
      xh >>>= 32;  //                                       xh  00000000000000000000000000000000HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
      yh >>>= 32;
      //           xh xm xl
      //  *        yh ym yl
      //  -----------------
      //              xl*yl
      //           xl*ym
      //           yl*xm
      //        xl*yh
      //        yl*xh
      //        xm*ym
      //     xm*yh
      //     ym*xh
      //  xh*yh
      //  -----------------
      //  zd    zc    zb
      long zb = xl * yl;  //60bit
      long zc = xl * yh + yl * xh + xm * ym;  //62bit*2+60bit
      long zd = xh * yh;  //64bit
      xl *= ym;  //xl*ym。60bit
      yl *= xm;  //yl*xm。60bit
      xm *= yh;  //xm*yh。62bit
      ym *= xh;  //ym*xh。62bit
      zb += (xl << -30 >>> 4) + (yl << -30 >>> 4);  //xl*ymの下位30bit<<30,yl*xmの下位30bit<<30。60bit*3
      zc += (xm << -30 >>> 4) + (ym << -30 >>> 4);  //xm*yhの下位30bit<<30,ym*xhの下位30bit<<30。62bit*2+60bit*3
      zc += (xl >>> 30) + (yl >>> 30) + (zb >>> -4);  //xl*ymの上位30bit,yl*xmの上位30bit,zbからのキャリー4bit。62bit*2+60bit*3+30bit*2+4bitで64bitに収まる
      zd += (xm >>> 30) + (ym >>> 30) + (zc >>> -4);  //xm*yhの上位32bit,ym*xhの上位32bit,zcからのキャリー4bit。積は92*2=184bitで64bit,60bit,60bitに収まる
      zb <<= 4;  //sticky bitにゴミが残っていると困るので使用済みのキャリーを押し出す
      zc <<= 4;  //使用済みのキャリーを押し出してzdとzcの隙間を詰める。zcの下位4bitに隙間ができるがsticky bitなのでzbを詰める必要はない
      //正規化する
      //  zdのMSBに隙間がないときは整数部が1+1=2bitになっているので指数部を1増やす
      if (zd < 0L) {
        ze++;
      } else {
        zd = zd << 1 | zc >>> -1;
        zc <<= 1;
      }
      return this.finish2 (zf, ze, zd, zc, zb);
    }  //efp.mul(EFP,EFP)
    public final EFP imul (EFP x, EFP y) {  //11.7
      int xf = x.flg;
      int yf = y.flg;
      {
        int o;
        if ((o = xf | yf) << 1 != 0) {  //どちらかが±0,±Inf,NaN
          if (o << 3 < 0) {  //どちらかがNaNのときNaN
            this.flg = N;
          } else if ((o &= (Z | I)) == (Z | I)) {  //±0*±InfのときNaN
            epbFpsr |= EPB_FPSR_OE;
            if (yf << 1 < 0) {  //±Inf*±0
              epbExceptionOperandExponent = yf & M;
              epbExceptionOperandMantissa = 0x0000000000000000L;
            } else {  //±0*±Inf
              epbExceptionOperandExponent = yf & M | 0x7fff << 16;
              epbExceptionOperandMantissa = 0x0000000000000000L;
            }
            this.flg = N;
          } else {  //両方±0,NaN以外でどちらかが±Infのとき±Inf、両方±Inf,NaN以外でどちらかが±0のとき±0
            this.flg = (xf ^ yf) & M | o;
          }
          return this;
        }
      }
      //符号
      int zf = xf ^ yf;  //符号が同じならばP、異なればM。ここでセットされるのはMだけ
      //指数部
      int ze = x.epp + y.epp;
      //以下はLEN<=92bitでなければならない
      //掛ける
      //  92bitの仮数部を32bit,30bit,30bitに3分割する
      //                                                                  111111111122222222223333333333444444444455555555556666
      //                                                        0123456789012345678901234567890123456789012345678901234567890123
      //                                                 x.dvl  HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLL
      //                                                 x.cvl  LLLLLLLLLLLLLLLLLLLLLLLLLLLL000000000000000000000000000000000000
      long xh = x.dvl;  //                                  xh  HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLL
      long yh = y.dvl;
      long xl = (xh << -2 | x.cvl >>> 2) >>> -30;  //   xh<<-2  LL00000000000000000000000000000000000000000000000000000000000000
      //                                             x.cvl>>>2  00LLLLLLLLLLLLLLLLLLLLLLLLLLLL0000000000000000000000000000000000
      //                                      xh<<-2|x.cvl>>>2  LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL0000000000000000000000000000000000
      //                                                    xl  0000000000000000000000000000000000LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
      long yl = (yh << -2 | y.cvl >>> 2) >>> -30;
      long xm = xh << 32 >>> -30;  //                   xh<<32  MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLL00000000000000000000000000000000
      //                                                    xm  0000000000000000000000000000000000MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
      long ym = yh << 32 >>> -30;
      xh >>>= 32;  //                                       xh  00000000000000000000000000000000HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
      yh >>>= 32;
      //           xh xm xl
      //  *        yh ym yl
      //  -----------------
      //              xl*yl
      //           xl*ym
      //           yl*xm
      //        xl*yh
      //        yl*xh
      //        xm*ym
      //     xm*yh
      //     ym*xh
      //  xh*yh
      //  -----------------
      //  zd    zc    zb
      long zb = xl * yl;  //60bit
      long zc = xl * yh + yl * xh + xm * ym;  //62bit*2+60bit
      long zd = xh * yh;  //64bit
      xl *= ym;  //xl*ym。60bit
      yl *= xm;  //yl*xm。60bit
      xm *= yh;  //xm*yh。62bit
      ym *= xh;  //ym*xh。62bit
      zb += (xl << -30 >>> 4) + (yl << -30 >>> 4);  //xl*ymの下位30bit<<30,yl*xmの下位30bit<<30。60bit*3
      zc += (xm << -30 >>> 4) + (ym << -30 >>> 4);  //xm*yhの下位30bit<<30,ym*xhの下位30bit<<30。62bit*2+60bit*3
      zc += (xl >>> 30) + (yl >>> 30) + (zb >>> -4);  //xl*ymの上位30bit,yl*xmの上位30bit,zbからのキャリー4bit。62bit*2+60bit*3+30bit*2+4bitで64bitに収まる
      zd += (xm >>> 30) + (ym >>> 30) + (zc >>> -4);  //xm*yhの上位32bit,ym*xhの上位32bit,zcからのキャリー4bit。積は92*2=184bitで64bit,60bit,60bitに収まる
      zb <<= 4;  //sticky bitにゴミが残っていると困るので使用済みのキャリーを押し出す
      zc <<= 4;  //使用済みのキャリーを押し出してzdとzcの隙間を詰める。zcの下位4bitに隙間ができるがsticky bitなのでzbを詰める必要はない
      //正規化する
      //  zdのMSBに隙間がないときは整数部が1+1=2bitになっているので指数部を1増やす
      if (zd < 0L) {
        ze++;
      } else {
        zd = zd << 1 | zc >>> -1;
        zc <<= 1;
      }
      return this.ifinish (zf, ze, zd, zc, zb);
    }  //efp.imul(EFP,EFP)

    //------------------------------------------------------------------------
    //x = x.mul2 ()
    //  x*=2
    //y = y.mul2 (x)
    //  y=x*2
    //  2倍
    //
    //  グラフ
    //    perl -e "use Graph;$g=new Graph();$g->grid();$g->func(sub{2*$_[0]});print$g"
    //    +---------+---------+---------+---------+---------+---------**--------+---------+
    //    |                                       |                  **                   |
    //    |                                       |                 **                    |
    //    |                                       |                **                     |
    //    |                                       |               **                      |
    //    +                                       +              **                       +
    //    |                                       |             **                        |
    //    |                                       |            **                         |
    //    |                                       |           **                          |
    //    |                                       |          **                           |
    //    +                                       +         **                            +
    //    |                                       |        **                             |
    //    |                                       |       **                              |
    //    |                                       |      **                               |
    //    |                                       |     **                                |
    //    +                                       +    **                                 +
    //    |                                       |   **                                  |
    //    |                                       |  **                                   |
    //    |                                       | **                                    |
    //    |                                       |**                                     |
    //    +---------+---------+---------+---------**--------+---------+---------+---------+
    //    |                                      **                                       |
    //    |                                     **|                                       |
    //    |                                    ** |                                       |
    //    |                                   **  |                                       |
    //    +                                  **   +                                       +
    //    |                                 **    |                                       |
    //    |                                **     |                                       |
    //    |                               **      |                                       |
    //    |                              **       |                                       |
    //    +                             **        +                                       +
    //    |                            **         |                                       |
    //    |                           **          |                                       |
    //    |                          **           |                                       |
    //    |                         **            |                                       |
    //    +                        **             +                                       +
    //    |                       **              |                                       |
    //    |                      **               |                                       |
    //    |                     **                |                                       |
    //    |                    **                 |                                       |
    //    +---------+---------**--------+---------+---------+---------+---------+---------+
    //    echo read("../misc/efp.gp");eval("mul2(x)=x*2");graph(mul2) | gp -q
    //    +---------+---------+---------+---------+---------+---------*---------+---------+
    //    |                                       |                  *                    |
    //    |                                       |                 *                     |
    //    |                                       |                *                      |
    //    |                                       |               *                       |
    //    +                                       +              *                        +
    //    |                                       |             *                         |
    //    |                                       |            *                          |
    //    |                                       |           *                           |
    //    |                                       |          *                            |
    //    +                                       +         *                             +
    //    |                                       |        *                              |
    //    |                                       |       *                               |
    //    |                                       |      *                                |
    //    |                                       |     *                                 |
    //    +                                       +    *                                  +
    //    |                                       |   *                                   |
    //    |                                       |  *                                    |
    //    |                                       | *                                     |
    //    |                                       |*                                      |
    //    +---------+---------+---------+---------*---------+---------+---------+---------+
    //    |                                      *|                                       |
    //    |                                     * |                                       |
    //    |                                    *  |                                       |
    //    |                                   *   |                                       |
    //    +                                  *    +                                       +
    //    |                                 *     |                                       |
    //    |                                *      |                                       |
    //    |                               *       |                                       |
    //    |                              *        |                                       |
    //    +                             *         +                                       +
    //    |                            *          |                                       |
    //    |                           *           |                                       |
    //    |                          *            |                                       |
    //    |                         *             |                                       |
    //    +                        *              +                                       +
    //    |                       *               |                                       |
    //    |                      *                |                                       |
    //    |                     *                 |                                       |
    //    |                    *                  |                                       |
    //    +---------+---------*---------+---------+---------+---------+---------+---------+
    //
    public final EFP mul2 () {
      return this.finish (this.flg, this.epp + 1, this.dvl, this.cvl, 0L);
    }  //efp.mul2()
    public final EFP imul2 () {
      this.epp++;
      return this;
    }  //efp.imul2()
    public final EFP mul2 (EFP x) {
      return this.finish (x.flg, x.epp + 1, x.dvl, x.cvl, 0L);
    }  //efp.mul2(EFP)
    public final EFP imul2 (EFP x) {
      this.flg = x.flg;
      this.epp = x.epp + 1;
      this.dvl = x.dvl;
      this.cvl = x.cvl;
      return this;
    }  //efp.imul2(EFP)

    //------------------------------------------------------------------------
    //x = x.mul3 ()
    //  x*=3
    //y = y.mul3 (x)
    //  y=x*3
    //  3倍
    //
    //  グラフ
    //    perl -e "use Graph;$g=new Graph();$g->grid();$g->func(sub{3*$_[0]});print$g"
    //    echo read("../misc/efp.gp");eval("mul3(x)=x*3");graph(mul3) | gp -q
    //    +---------+---------+---------+---------+---------+--**-----+---------+---------+
    //    |                                       |           **                          |
    //    |                                       |           *                           |
    //    |                                       |          **                           |
    //    |                                       |         **                            |
    //    +                                       +         *                             +
    //    |                                       |        **                             |
    //    |                                       |       **                              |
    //    |                                       |       *                               |
    //    |                                       |      **                               |
    //    +                                       +     **                                +
    //    |                                       |     *                                 |
    //    |                                       |    **                                 |
    //    |                                       |   **                                  |
    //    |                                       |   *                                   |
    //    +                                       +  **                                   +
    //    |                                       | **                                    |
    //    |                                       | *                                     |
    //    |                                       |**                                     |
    //    |                                       **                                      |
    //    +---------+---------+---------+---------*---------+---------+---------+---------+
    //    |                                      **                                       |
    //    |                                     **|                                       |
    //    |                                     * |                                       |
    //    |                                    ** |                                       |
    //    +                                   **  +                                       +
    //    |                                   *   |                                       |
    //    |                                  **   |                                       |
    //    |                                 **    |                                       |
    //    |                                 *     |                                       |
    //    +                                **     +                                       +
    //    |                               **      |                                       |
    //    |                               *       |                                       |
    //    |                              **       |                                       |
    //    |                             **        |                                       |
    //    +                             *         +                                       +
    //    |                            **         |                                       |
    //    |                           **          |                                       |
    //    |                           *           |                                       |
    //    |                          **           |                                       |
    //    +---------+---------+-----**--+---------+---------+---------+---------+---------+
    //
    public final EFP mul3 () {
      return this.muli (this, 3);
    }  //efp.mul3()
    public final EFP mul3 (EFP x) {
      //return this.muli (x, 3);  //x*3
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        this.flg = xf;
        return this;
      }
      //±0,±Inf,NaN以外
      int ze = x.epp + 1;
      long zd = x.dvl;
      long zc = x.cvl;
      long t = zc;
      zc += (zc >>> 1);  //bit63が1→0のときcから溢れている
      zd += (zd >>> 1) + ((zc & ~t) >>> -1);  //bit63が1→0のときdから溢れている
      if (zd >= 0L) {  //2bit増えた
        zc = zd << -1 | zc >>> 1;
        zd = MSB | zd >>> 1;
        ze++;
      }
      return this.finish (xf, ze, zd, zc, 0L);
    }  //efp.mul3(EFP)

    //------------------------------------------------------------------------
    //x = x.muli (n)
    //  x*=n
    //z = z.muli (x, n)
    //  z=x*n
    //  int乗算
    //
    public final EFP muli (int n) {
      return this.muli (this, n);
    }  //efp.muli(int)
    public final EFP muli (EFP x, int n) {
      //return this.mul (x, new EFP (n));  //x*n
      int xf = x.flg;
      if (n == 0) {  //0倍
        this.flg = (xf & (I | N)) != 0 ? N : xf | Z;  //±Inf*0=NaN, NaN*0=NaN, ±0*0=±0, ±x*0=±0
        return this;
      }
      if (xf << 1 != 0) {  //xが±0,±Inf,NaN
        this.flg = xf << 3 < 0 ? N : xf ^ (n & M);  //NaN*±n=NaN, ±Inf*±n=±Inf, ±0*±n=±0
        return this;
      }
      //両方±0,±Inf,NaN以外
      int ze = x.epp;
      long zd = x.dvl;
      long zc = x.cvl;
      if (n < 0) {  //乗数が負
        xf ^= M;
        if (n == 0x80000000) {
          ze += 31;
          if ((short) ze != ze) {  //オーバーフロー
            epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
            epbExceptionOperandExponent = xf;
            epbExceptionOperandMantissa = zd;
            return this.sete (OVFL_RESULTS[epbRoundingPrec << 3 | epbRoundingMode << 1 | xf >>> 31]).finish ();  //±Inf
          }
          this.flg = xf;
          this.epp = ze;
          this.dvl = zd;
          this.cvl = zc;
          return this;
        }
        n = -n;
      }
      if (n > 1) {
        long y = (long) n;  //0x80000000は処理済みなので0xffffffffLでマスクする必要はない
        //掛ける
        //     x0 x1 x2
        //  *        y0
        //  -----------
        //        x2*y0
        //     x1*y0
        //  x0*y0
        //  -----------
        //     zd    zc
        zc = (zc >>> 32) * y;
        long t = (zd & 0xffffffffL) * y + (zc >>> 32);
        zc = t << 32 | (zc & 0xffffffffL);
        zd = (zd >>> 32) * y + (t >>> 32);
        //正規化する
        int o = Long.numberOfLeadingZeros (zd);
        ze += 32 - o;
        if (o > 0) {
          zd = zd << o | zc >>> -o;
          zc <<= o;
        }
      }
      return this.finish (xf, ze, zd, zc, 0L);
    }  //efp.muli(EFP,int)

    //------------------------------------------------------------------------
    //x = x.mulpi ()
    //  x*=pi
    //y = y.mulpi (x)
    //  y=x*pi
    //  円周率倍
    //
    //  グラフ
    //    perl -e "use Graph;$g=new Graph();$g->grid();$g->func(sub{4*atan2(1,1)*$_[0]});print$g"
    //    echo read("../misc/efp.gp");eval("mulpi(x)=x*Pi");graph(mulpi) | gp -q
    //    +---------+---------+---------+---------+---------+-**------+---------+---------+
    //    |                                       |           *                           |
    //    |                                       |          **                           |
    //    |                                       |          *                            |
    //    |                                       |         **                            |
    //    +                                       +        **                             +
    //    |                                       |        *                              |
    //    |                                       |       **                              |
    //    |                                       |      **                               |
    //    |                                       |      *                                |
    //    +                                       +     **                                +
    //    |                                       |    **                                 |
    //    |                                       |    *                                  |
    //    |                                       |   **                                  |
    //    |                                       |   *                                   |
    //    +                                       +  **                                   +
    //    |                                       | **                                    |
    //    |                                       | *                                     |
    //    |                                       |**                                     |
    //    |                                       **                                      |
    //    +---------+---------+---------+---------*---------+---------+---------+---------+
    //    |                                      **                                       |
    //    |                                     **|                                       |
    //    |                                     * |                                       |
    //    |                                    ** |                                       |
    //    +                                   **  +                                       +
    //    |                                   *   |                                       |
    //    |                                  **   |                                       |
    //    |                                  *    |                                       |
    //    |                                 **    |                                       |
    //    +                                **     +                                       +
    //    |                                *      |                                       |
    //    |                               **      |                                       |
    //    |                              **       |                                       |
    //    |                              *        |                                       |
    //    +                             **        +                                       +
    //    |                            **         |                                       |
    //    |                            *          |                                       |
    //    |                           **          |                                       |
    //    |                           *           |                                       |
    //    +---------+---------+------**-+---------+---------+---------+---------+---------+
    //
    public final EFP mulpi () {
      return this.mul (this, PI);
    }  //efp.mulpi()
    public final EFP mulpi (EFP x) {
      return this.mul (x, PI);  //x*pi
    }  //efp.mulpi(EFP)

    //------------------------------------------------------------------------
    //z = z.imulw (w, x, y)
    //  z+w=x*y
    //  倍精度乗算
    //  zはz.imul(x,y)の結果と等しい
    //  zはnearest-evenで丸められる
    //  wの符号はzの符号と同じとは限らない
    //  wの絶対値はulp(z)/2以下
    //  結果は常に正確
    //
    public final EFP imulw (EFP w, EFP x, EFP y) {
      int xf = x.flg;
      int yf = y.flg;
      {
        int o;
        if ((o = xf | yf) << 1 != 0) {  //どちらかが±0,±Inf,NaN
          if (o << 3 < 0) {  //どちらかがNaNのときNaN
            this.flg = N;
          } else if ((o &= (Z | I)) == (Z | I)) {  //±0*±InfのときNaN
            epbFpsr |= EPB_FPSR_OE;
            if (yf << 1 < 0) {  //±Inf*±0
              epbExceptionOperandExponent = yf & M;
              epbExceptionOperandMantissa = 0x0000000000000000L;
            } else {  //±0*±Inf
              epbExceptionOperandExponent = yf & M | 0x7fff << 16;
              epbExceptionOperandMantissa = 0x0000000000000000L;
            }
            this.flg = N;
          } else {  //両方±0,NaN以外でどちらかが±Infのとき±Inf、両方±Inf,NaN以外でどちらかが±0のとき±0
            this.flg = (xf ^ yf) & M | o;
          }
          w.flg = this.flg;  //zが±0,±Inf,NaNのときwも±0,±Inf,NaN
          return this;
        }
      }
      //符号
      int zf = xf ^ yf;  //符号が同じならばP、異なればM。ここでセットされるのはMだけ
      //指数部
      int ze = x.epp + y.epp;
      //以下はLEN<=92bitでなければならない
      //掛ける
      //  92bitの仮数部を32bit,30bit,30bitに3分割する
      //                                                                  111111111122222222223333333333444444444455555555556666
      //                                                        0123456789012345678901234567890123456789012345678901234567890123
      //                                                 x.dvl  HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLL
      //                                                 x.cvl  LLLLLLLLLLLLLLLLLLLLLLLLLLLL000000000000000000000000000000000000
      long xh = x.dvl;  //                                  xh  HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLL
      long yh = y.dvl;
      long xl = (xh << -2 | x.cvl >>> 2) >>> -30;  //   xh<<-2  LL00000000000000000000000000000000000000000000000000000000000000
      //                                             x.cvl>>>2  00LLLLLLLLLLLLLLLLLLLLLLLLLLLL0000000000000000000000000000000000
      //                                      xh<<-2|x.cvl>>>2  LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL0000000000000000000000000000000000
      //                                                    xl  0000000000000000000000000000000000LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
      long yl = (yh << -2 | y.cvl >>> 2) >>> -30;
      long xm = xh << 32 >>> -30;  //                   xh<<32  MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMLL00000000000000000000000000000000
      //                                                    xm  0000000000000000000000000000000000MMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
      long ym = yh << 32 >>> -30;
      xh >>>= 32;  //                                       xh  00000000000000000000000000000000HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
      yh >>>= 32;
      //           xh xm xl
      //  *        yh ym yl
      //  -----------------
      //              xl*yl
      //           xl*ym
      //           yl*xm
      //        xl*yh
      //        yl*xh
      //        xm*ym
      //     xm*yh
      //     ym*xh
      //  xh*yh
      //  -----------------
      //  zd    zc    zb
      long zb = xl * yl;  //60bit
      long zc = xl * yh + yl * xh + xm * ym;  //62bit*2+60bit
      long zd = xh * yh;  //64bit
      xl *= ym;  //xl*ym。60bit
      yl *= xm;  //yl*xm。60bit
      xm *= yh;  //xm*yh。62bit
      ym *= xh;  //ym*xh。62bit
      zb += (xl << -30 >>> 4) + (yl << -30 >>> 4);  //xl*ymの下位30bit<<30,yl*xmの下位30bit<<30。60bit*3
      zc += (xm << -30 >>> 4) + (ym << -30 >>> 4);  //xm*yhの下位30bit<<30,ym*xhの下位30bit<<30。62bit*2+60bit*3
      zc += (xl >>> 30) + (yl >>> 30) + (zb >>> -4);  //xl*ymの上位30bit,yl*xmの上位30bit,zbからのキャリー4bit。62bit*2+60bit*3+30bit*2+4bitで64bitに収まる
      zd += (xm >>> 30) + (ym >>> 30) + (zc >>> -4);  //xm*yhの上位32bit,ym*xhの上位32bit,zcからのキャリー4bit。積は92*2=184bitで64bit,60bit,60bitに収まる
      zb <<= 4;  //使用済みのキャリーを押し出す
      zc = zc << 4 | zb >>> -4;  //使用済みのキャリーを押し出してzbから4bit持ってくる
      zb <<= 4;
      //上位を正規化する
      //  zdのMSBに隙間がないときは整数部が1+1=2bitになっているので指数部を1増やす
      if (zd < 0L) {
        ze++;
      } else {
        zd = zd << 1 | zc >>> -1;
        zc = zc << 1 | zb >>> -1;
        zb <<= 1;
      }
      //積を上位と下位に分ける
      //                111111111122222222223333333333444444444455555555556666
      //      0123456789012345678901234567890123456789012345678901234567890123
      //  zd  HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
      //  zc  hhhhhhhhhhhhhhhhhhhhhhhhhhhhLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
      //  zb  llllllllllllllllllllllllllllllllllllllllllllllllllllllll00000000
      //  zd  HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
      //  zc  hhhhhhhhhhhhhhhhhhhhhhhhhhhh000000000000000000000000000000000000
      //  wd  LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLllllllllllllllllllllllllllll
      //  wc  llllllllllllllllllllllllllll000000000000000000000000000000000000
      int wf = zf;
      int we = ze - LEN;
      long wd = zc << LEN - 64 | zb >>> -(LEN - 64);
      long wc = zb << LEN - 64;
      zc &= -LSB;
      //zb = 0L;
      //下位の絶対値を上位の1/2ulp以下にする
      if (wd < 0L && (zc & LSB | wd << 1 | wc) != 0L) {  //guard bitが1かつLSBとround bitとsticky bitのいずれかが0でない
        //下位からLSBを引く(LSBから下位を引いて符号を反転する)
        wf ^= M;
        wc = -(wc >>> 1);
        wd = -wd - (wc >>> -1);
        wc <<= 1;
        //上位にLSBを加える
        if ((zc += LSB) == 0L && ++zd == 0L) {  //LSBを加えて、溢れたとき
          zd = MSB;  //MSBだけセットして
          ze++;  //指数部を1増やす
        }
      }
      //下位を正規化する
      if (wd >= 0L) {  //正規化が必要
        if (wd != 0L) {
          int o = Long.numberOfLeadingZeros (wd);  //1以上
          we -= o;
          wd = wd << o | wc >>> -o;  //o==0は不可
          wc <<= o;
        } else if (wc != 0L) {
          int o = Long.numberOfLeadingZeros (wc);  //0以上
          we -= 64 + o;
          wd = wc << o;
          wc = 0L;
        } else {
          wf |= Z;
        }
      }
      //結果
      if (ze > 32767) {  //オーバーフロー
        epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
        epbExceptionOperandExponent = zf;
        epbExceptionOperandMantissa = zd;
        return this.sete (w.sete (OVFL_RESULTS[epbRoundingPrec << 3 | epbRoundingMode << 1 | zf >>> 31]));  //±Inf
      } else if (ze < -32768 || wf << 1 >= 0 && we < -32768) {  //アンダーフロー
        epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
        epbExceptionOperandExponent = zf;
        epbExceptionOperandMantissa = zd;
        return this.sete (w.sete (UNFL_RESULTS[epbRoundingPrec << 3 | epbRoundingMode << 1 | zf >>> 31]));  //±0
      } else {
        this.flg = zf;
        this.epp = ze;
        this.dvl = zd;
        this.cvl = zc;
        w.flg = wf;
        w.epp = we;
        w.dvl = wd;
        w.cvl = wc;
        return this;
      }
    }  //efp.imulw(EFP,EFP,EFP)

    //------------------------------------------------------------------------
    //b = x.ne (y)
    //  b=x!=y
    //  等しくないか
    //
    //  -Inf==-Inf<-x<-0==+0<+x<+Inf==+Inf
    //
    //  NaNの扱い
    //    どちらかがNaNのときはtrueを返す
    //
    public boolean ne (EFP y) {
      int xf = this.flg;
      int yf = y.flg;
      return ((xf | yf) << 1 != 0 ?  //どちらかが±0,±Inf,NaN
              EFP_NE_TABLE[xf >>> 28] << (yf >>> 28 - 1) < 0
              : //両方±0,±Inf,NaN以外
              xf != yf || this.epp != y.epp || this.dvl != y.dvl || this.cvl != y.cvl);
    }  //efp.ne(EFP)

    //------------------------------------------------------------------------
    //x = x.neg ()
    //  x=-x
    //y = y.neg (x)
    //  y=-x
    //  符号反転
    //x = x.neg (b)
    //  x=b?-x:x
    //y = y.neg (x, b)
    //  y=b?-x:x
    //  条件付き符号反転
    //
    //  グラフ
    //    perl -e "use Graph;$g=new Graph();$g->grid();$g->func(sub{-$_[0]});print$g"
    //    echo read("../misc/efp.gp");eval("neg(x)=-x");graph(neg) | gp -q
    //    **--------+---------+---------+---------+---------+---------+---------+---------+
    //    |***                                    |                                       |
    //    |  ***                                  |                                       |
    //    |    ***                                |                                       |
    //    |      ***                              |                                       |
    //    +        ***                            +                                       +
    //    |          ***                          |                                       |
    //    |            ***                        |                                       |
    //    |              ***                      |                                       |
    //    |                ***                    |                                       |
    //    +                  ***                  +                                       +
    //    |                    ***                |                                       |
    //    |                      ***              |                                       |
    //    |                        ***            |                                       |
    //    |                          ***          |                                       |
    //    +                            ***        +                                       +
    //    |                              ***      |                                       |
    //    |                                ***    |                                       |
    //    |                                  ***  |                                       |
    //    |                                    ***|                                       |
    //    +---------+---------+---------+--------***--------+---------+---------+---------+
    //    |                                       |***                                    |
    //    |                                       |  ***                                  |
    //    |                                       |    ***                                |
    //    |                                       |      ***                              |
    //    +                                       +        ***                            +
    //    |                                       |          ***                          |
    //    |                                       |            ***                        |
    //    |                                       |              ***                      |
    //    |                                       |                ***                    |
    //    +                                       +                  ***                  +
    //    |                                       |                    ***                |
    //    |                                       |                      ***              |
    //    |                                       |                        ***            |
    //    |                                       |                          ***          |
    //    +                                       +                            ***        +
    //    |                                       |                              ***      |
    //    |                                       |                                ***    |
    //    |                                       |                                  ***  |
    //    |                                       |                                    ***|
    //    +---------+---------+---------+---------+---------+---------+---------+--------**
    //
    public final EFP neg () {
      return this.finish (0 <= this.flg << 3 ? this.flg ^ M : this.flg, this.epp, this.dvl, this.cvl, 0L);  //NaN以外のとき符号反転
    }  //efp.neg()
    public final EFP ineg () {
      if (0 <= this.flg << 3) {  //NaN以外のとき
        this.flg ^= M;  //符号反転
      }
      return this;
    }  //efp.ineg()
    public final EFP neg (boolean b) {
      return this.finish (b && 0 <= this.flg << 3 ? this.flg ^ M : this.flg, this.epp, this.dvl, this.cvl, 0L);  //bかつNaN以外のとき符号反転
    }  //efp.neg(boolean)
    public final EFP ineg (boolean b) {
      if (b && 0 <= this.flg << 3) {  //bかつNaN以外のとき
        this.flg ^= M;  //符号反転
      }
      return this;
    }  //efp.ineg(boolean)
    public final EFP neg (EFP x) {
      return this.finish (0 <= x.flg << 3 ? x.flg ^ M : x.flg, x.epp, x.dvl, x.cvl, 0L);  //NaN以外のとき符号反転
    }  //efp.neg(EFP)
    public final EFP ineg (EFP x) {
      this.flg = 0 <= x.flg << 3 ? x.flg ^ M : x.flg;  //NaN以外のとき符号反転
      this.epp = x.epp;
      this.dvl = x.dvl;
      this.cvl = x.cvl;
      return this;
    }  //efp.ineg(EFP)
    public final EFP neg (EFP x, boolean b) {
      return this.finish (b && 0 <= x.flg << 3 ? x.flg ^ M : x.flg, x.epp, x.dvl, x.cvl, 0L);  //bかつNaN以外のとき符号反転
    }  //efp.neg(EFP,boolean)
    public final EFP ineg (EFP x, boolean b) {
      this.flg = b && 0 <= x.flg << 3 ? x.flg ^ M : x.flg;  //bかつNaN以外のとき符号反転
      this.epp = x.epp;
      this.dvl = x.dvl;
      this.cvl = x.cvl;
      return this;
    }  //efp.ineg(EFP,boolean)

    //------------------------------------------------------------------------
    //x = x.negdec ()
    //  x=1-x
    //y = y.negdec (x)
    //  y=1-x
    //  1から引く(逆デクリメント)
    //
    //  x.dec(y).neg()と同じ
    //
    public final EFP negdec () {
      return this.inner ().dec ().outer ().neg (0 <= this.flg << 1);  //x-1==+0のとき1-x==+0にするため符号反転しない
    }  //efp.negdec()
    public final EFP negdec (EFP x) {
      return this.inner ().dec (x).outer ().neg (0 <= this.flg << 1);  //x-1==+0のとき1-x==+0にするため符号反転しない
    }  //efp.negdec(EFP)

    //------------------------------------------------------------------------
    //y = y.negset0 ()
    //  -0代入
    //
    public final EFP negset0 () {
      this.flg = M | Z;
      //this.epp = 0;
      //this.dvl = 0L;
      //this.cvl = 0L;
      return this;
    }  //efp.negset0()

    //------------------------------------------------------------------------
    //y = y.negset1 ()
    //  -1代入
    //
    public final EFP negset1 () {
      this.flg = M;
      this.epp = 0;
      this.dvl = MSB;
      this.cvl = 0L;
      return this;
    }  //efp.negset1()

    //------------------------------------------------------------------------
    //y = y.negsetinf ()
    //  -Inf代入
    //
    public final EFP negsetinf () {
      this.flg = M | I;
      //this.epp = 0;
      //this.dvl = 0L;
      //this.cvl = 0L;
      return this;
    }  //efp.negsetinf()

    //------------------------------------------------------------------------
    //x = x.negsub (y)
    //  x=y-x
    //  逆減算
    //
    //  x.sub(y).neg()と同じ
    //  z.negsub(x,y)はz.sub(y,x)と同じ
    //
    public final EFP negsub (EFP y) {
      int xf = y.flg;
      int xe = y.epp;
      long xd = y.dvl;
      long xc = y.cvl;
      long xb = 0L;
      int yf = this.flg;
      if ((xf | yf) << 1 != 0) {  //どちらかが±0,±Inf,NaN
        if ((xf | yf) << 3 < 0) {  //どちらかがNaNのときNaN
          this.flg = N;
          return this;
        }
        if ((xf & yf) << 2 < 0 && xf == yf) {  //両方±Infで符号が同じときNaN
          epbFpsr |= EPB_FPSR_OE;
          epbExceptionOperandExponent = yf & M | 0x7fff << 16;
          epbExceptionOperandMantissa = 0x0000000000000000L;
          this.flg = N;
          return this;
        }
        if ((xf & yf) << 1 < 0 && xf == yf) {  //両方±0で符号が同じとき
          this.flg = epbRoundingMode == EPB_MODE_RM ? M | Z : P | Z;  //RMのとき-0,それ以外は+0
          return this;
        }
        if (xf << 1 < 0 || yf << 2 < 0) {  //xが±0またはyが±Infのとき-y
          xf = yf ^ M;
          xe = this.epp;
          xd = this.dvl;
          xc = this.cvl;
        }
        //xが±Infまたはyが±0のときx
      } else {  //両方±0,±Inf,NaN以外
        //減算なのでyの符号を反転して加算する
        yf ^= M;
        long yd = this.dvl;
        long yc = this.cvl;
        int o = xe - this.epp;
        if (o < 0 || o == 0 && (xd < yd || xd == yd && xc >>> 1 < yc >>> 1)) {  //yの方が絶対値が大きい
          //xとyを入れ換える
          xf = yf;
          xe += o = -o;  //xe=this.epp
          xd = yd;
          xc = yc;
          yf = y.flg;  //後で符号を比較するときに使う
          yd = y.dvl;
          yc = y.cvl;
        }
        //xの方が絶対値が大きいか等しい
        //yを右にずらして小数点の位置を合わせる
        if (0 < o) {
          if (o <= 63) {
            xb = yc << -o;
            yc = yd << -o | yc >>> o;
            yd >>>= o;
          } else if (o == 64) {
            xb = yc;
            yc = yd;
            yd = 0L;
          } else if (o <= 127) {
            xb = yd << -o | yc;
            yc = yd >>> o;
            yd = 0L;
          } else {
            xb = yd | yc;  //絶対値減算を行うとき下位からのボローとして必要
            yc = 0L;
            yd = 0L;
          }
        }
        //絶対値加算または絶対値減算を行う
        if (xf == yf) {  //符号が同じなので絶対値加算を行う
          //yc[1]とyc[0]をsticky bitに押し出す
          xb |= yc << 62;
          //右にずらしてxd[63]を空ける
          xc = xd << 63 | xc >>> 1;
          xd >>>= 1;
          yc = yd << 63 | yc >>> 1;
          yd >>>= 1;
          //下位を右にずらしてxc[63]を空ける
          yc >>>= 1;
          xc >>>= 1;
          //足す
          xc += yc;
          xd += yd + (xc >>> 63);
          //下位を左にずらしてxc[63]を詰める
          xc <<= 1;
          //溢れの処理
          if (xd < 0L) {  //溢れたとき
            xe++;
          } else {  //溢れなかったとき
            xd = xd << 1 | xc >>> 63;  //左にずらしてxd[63]を詰める
            xc <<= 1;
          }
        } else {  //符号が異なるので絶対値減算を行う
          //yc[0]をsticky bitに押し出す
          xb |= yc << 63;
          //下位を右にずらしてxc[63]を空ける
          yc >>>= 1;
          xc >>>= 1;
          //引く
          //  xの方が絶対値が大きいか等しいので負になることはないが0になることがある
          if (xb != 0L) {
            xc--;
          }
          xc -= yc;
          xd -= yd + (xc >>> 63);
          //下位を左にずらしてxc[63]を詰める
          xc <<= 1;
          //正規化する
          if (0L <= xd) {
            if (xd != 0L) {
              xe -= o = Long.numberOfLeadingZeros (xd);
              xd = xd << o | xc >>> -o;
              xc <<= o;
            } else if (xc != 0L) {
              xe -= o = 64 + Long.numberOfLeadingZeros (xc);
              xd = xc << o;
              xc = 0L;
            } else {  //0になった
              xf = epbRoundingMode == EPB_MODE_RM ? M | Z : P | Z;  //RMのとき-0,それ以外は+0
            }
          }
        }  //if 符号が同じなので絶対値加算を行う/符号が異なるので絶対値減算を行う
      }  //if どちらかが±0,±Inf,NaN/両方±0,±Inf,NaN以外
      return this.finish (xf, xe, xd, xc, xb);
    }  //efp.negsub(EFP)
    public final EFP negsub (EFP x, EFP y) {
      int xf = y.flg;
      int xe = y.epp;
      long xd = y.dvl;
      long xc = y.cvl;
      long xb = 0L;
      int yf = x.flg;
      if ((xf | yf) << 1 != 0) {  //どちらかが±0,±Inf,NaN
        if ((xf | yf) << 3 < 0) {  //どちらかがNaNのときNaN
          this.flg = N;
          return this;
        }
        if ((xf & yf) << 2 < 0 && xf == yf) {  //両方±Infで符号が同じときNaN
          epbFpsr |= EPB_FPSR_OE;
          epbExceptionOperandExponent = yf & M | 0x7fff << 16;
          epbExceptionOperandMantissa = 0x0000000000000000L;
          this.flg = N;
          return this;
        }
        if ((xf & yf) << 1 < 0 && xf == yf) {  //両方±0で符号が同じとき
          this.flg = epbRoundingMode == EPB_MODE_RM ? M | Z : P | Z;  //RMのとき-0,それ以外は+0
          return this;
        }
        if (xf << 1 < 0 || yf << 2 < 0) {  //xが±0またはyが±Infのとき-y
          xf = yf ^ M;
          xe = x.epp;
          xd = x.dvl;
          xc = x.cvl;
        }
        //xが±Infまたはyが±0のときx
      } else {  //両方±0,±Inf,NaN以外
        //減算なのでyの符号を反転して加算する
        yf ^= M;
        long yd = x.dvl;
        long yc = x.cvl;
        int o = xe - x.epp;
        if (o < 0 || o == 0 && (xd < yd || xd == yd && xc >>> 1 < yc >>> 1)) {  //yの方が絶対値が大きい
          //xとyを入れ換える
          xf = yf;
          xe += o = -o;  //xe=x.epp
          xd = yd;
          xc = yc;
          yf = y.flg;  //後で符号を比較するときに使う
          yd = y.dvl;
          yc = y.cvl;
        }
        //xの方が絶対値が大きいか等しい
        //yを右にずらして小数点の位置を合わせる
        if (0 < o) {
          if (o <= 63) {
            xb = yc << -o;
            yc = yd << -o | yc >>> o;
            yd >>>= o;
          } else if (o == 64) {
            xb = yc;
            yc = yd;
            yd = 0L;
          } else if (o <= 127) {
            xb = yd << -o | yc;
            yc = yd >>> o;
            yd = 0L;
          } else {
            xb = yd | yc;  //絶対値減算を行うとき下位からのボローとして必要
            yc = 0L;
            yd = 0L;
          }
        }
        //絶対値加算または絶対値減算を行う
        if (xf == yf) {  //符号が同じなので絶対値加算を行う
          //yc[1]とyc[0]をsticky bitに押し出す
          xb |= yc << 62;
          //右にずらしてxd[63]を空ける
          xc = xd << 63 | xc >>> 1;
          xd >>>= 1;
          yc = yd << 63 | yc >>> 1;
          yd >>>= 1;
          //下位を右にずらしてxc[63]を空ける
          yc >>>= 1;
          xc >>>= 1;
          //足す
          xc += yc;
          xd += yd + (xc >>> 63);
          //下位を左にずらしてxc[63]を詰める
          xc <<= 1;
          //溢れの処理
          if (xd < 0L) {  //溢れたとき
            xe++;
          } else {  //溢れなかったとき
            xd = xd << 1 | xc >>> 63;  //左にずらしてxd[63]を詰める
            xc <<= 1;
          }
        } else {  //符号が異なるので絶対値減算を行う
          //yc[0]をsticky bitに押し出す
          xb |= yc << 63;
          //下位を右にずらしてxc[63]を空ける
          yc >>>= 1;
          xc >>>= 1;
          //引く
          //  xの方が絶対値が大きいか等しいので負になることはないが0になることがある
          if (xb != 0L) {
            xc--;
          }
          xc -= yc;
          xd -= yd + (xc >>> 63);
          //下位を左にずらしてxc[63]を詰める
          xc <<= 1;
          //正規化する
          if (0L <= xd) {
            if (xd != 0L) {
              xe -= o = Long.numberOfLeadingZeros (xd);
              xd = xd << o | xc >>> -o;
              xc <<= o;
            } else if (xc != 0L) {
              xe -= o = 64 + Long.numberOfLeadingZeros (xc);
              xd = xc << o;
              xc = 0L;
            } else {  //0になった
              xf = epbRoundingMode == EPB_MODE_RM ? M | Z : P | Z;  //RMのとき-0,それ以外は+0
            }
          }
        }  //if 符号が同じなので絶対値加算を行う/符号が異なるので絶対値減算を行う
      }  //if どちらかが±0,±Inf,NaN/両方±0,±Inf,NaN以外
      return this.finish (xf, xe, xd, xc, xb);
    }  //efp.negsub(EFP,EFP)

    //------------------------------------------------------------------------
    //x = x.nextdowne ()
    //y = y.nextdowne (x)
    //  EFPで表現できるxの-Inf側の隣接値
    //x = x.nextdownd ()
    //y = y.nextdownd (x)
    //  doubleで表現できるxよりも小さい最大の値
    //x = x.nextdownf ()
    //y = y.nextdownf (x)
    //  floatで表現できるxよりも小さい最大の値
    //x = x.nextdownx ()
    //y = y.nextdownx (x)
    //  extendedで表現できるxよりも小さい最大の値
    //x = x.nextdowny ()
    //y = y.nextdowny (x)
    //  tripleで表現できるxよりも小さい最大の値
    //x = x.nextdown (prec)
    //y = y.nextdown (x, prec)
    //  precの精度で表現できるxよりも小さい最大の値
    //
    //  nextdown(±0)=負の最小値
    //  nextdown(+Inf)=最大値
    //  nextdown(-Inf)=-Inf
    //  nextdown(NaN)=NaN
    //  nextdown(最小値)=-Inf
    //
    public final EFP nextdowne () {
      return this.nextdowne (this);
    }  //efp.nextdowne()
    public final EFP nextdowne (EFP x) {
      int xf = x.flg;
      int xe = x.epp;
      long xd = x.dvl;
      long xc = x.cvl;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        if (xf << 1 < 0) {  //±0
          xf = M;  //負の最大値
          xe = -32768;
          xd = MSB;
          xc = 0L;
        } else if (xf == (P | I)) {  //+Inf
          xf = P;  //最大値
          xe = 32767;
          xd = -1L;
          xc = -1L << 128 - LEN;
        }
        //-Inf,NaNはそのまま
      } else if (xf >= 0) {  //+x
        if (xc != 0L) {
          xc -= 1L << 128 - LEN;  //最下位bitから1を引く
        } else if (xd != MSB) {
          xc = -1L << 128 - LEN;
          xd--;
        } else if (xe > -32768) {
          xc = -1L << 128 - LEN;
          xd = -1L;
          xe--;
        } else {  //アンダーフロー
          epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
          epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
          epbExceptionOperandMantissa = xd;
          return this.set0 ();  //+0
        }
      } else {  //-x
        if (xc != -1L << 128 - LEN) {
          xc += (1L << 128 - LEN);  //最下位bitに1を加える
        } else if (xd != -1L) {
          xc = 0L;
          xd++;
        } else if (xe < 32767) {
          xc = 0L;
          xd = MSB;
          xe++;
        } else {  //オーバーフロー
          epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
          epbExceptionOperandExponent = xf;
          epbExceptionOperandMantissa = xd;
          return this.negsetinf ();  //-Inf
        }
      }
      this.flg = xf;
      this.epp = xe;
      this.dvl = xd;
      this.cvl = xc;
      return this;
    }  //efp.nextdowne(EFP)
    public final EFP nextdownd () {
      return this.nextdowne (this).roundd (EPB_MODE_RM);
    }  //efp.nextdownd()
    public final EFP nextdownd (EFP x) {
      return this.nextdowne (x).roundd (EPB_MODE_RM);
    }  //efp.nextdownd(EFP)
    public final EFP nextdownf () {
      return this.nextdowne (this).roundf (EPB_MODE_RM);
    }  //efp.nextdownf()
    public final EFP nextdownf (EFP x) {
      return this.nextdowne (x).roundf (EPB_MODE_RM);
    }  //efp.nextdownf(EFP)
    public final EFP nextdowng () {
      return this.nextdowne (this).roundg (EPB_MODE_RM);
    }  //efp.nextdowng()
    public final EFP nextdowng (EFP x) {
      return this.nextdowne (x).roundg (EPB_MODE_RM);
    }  //efp.nextdowng(EFP)
    public final EFP nextdownx () {
      return this.nextdowne (this).roundx (EPB_MODE_RM);
    }  //efp.nextdownx()
    public final EFP nextdownx (EFP x) {
      return this.nextdowne (x).roundx (EPB_MODE_RM);
    }  //efp.nextdownx(EFP)
    public final EFP nextdowny () {
      return this.nextdowne (this).roundy (EPB_MODE_RM);
    }  //efp.nextdowny()
    public final EFP nextdowny (EFP x) {
      return this.nextdowne (x).roundy (EPB_MODE_RM);
    }  //efp.nextdowny(EFP)
    public final EFP nextdown (int prec) {
      switch (prec) {
      case EPB_PREC_EXD:
        return this.nextdowne (this).roundx (EPB_MODE_RM);
      case EPB_PREC_SGL:
        return this.nextdowne (this).roundf (EPB_MODE_RM);
      case EPB_PREC_DBL:
      case EPB_PREC_DBL3:
        return this.nextdowne (this).roundd (EPB_MODE_RM);
      case EPB_PREC_TPL:
        return this.nextdowne (this).roundy (EPB_MODE_RM);
      case EPB_PREC_XSG:
        return this.nextdowne (this).roundg (EPB_MODE_RM);
      }
      return this.nextdowne (this);
    }  //efp.nextdown(int)
    public final EFP nextdown (EFP x, int prec) {
      switch (prec) {
      case EPB_PREC_EXD:
        return this.nextdowne (x).roundx (EPB_MODE_RM);
      case EPB_PREC_SGL:
        return this.nextdowne (x).roundf (EPB_MODE_RM);
      case EPB_PREC_DBL:
      case EPB_PREC_DBL3:
        return this.nextdowne (x).roundd (EPB_MODE_RM);
      case EPB_PREC_TPL:
        return this.nextdowne (x).roundy (EPB_MODE_RM);
      case EPB_PREC_XSG:
        return this.nextdowne (x).roundg (EPB_MODE_RM);
      }
      return this.nextdowne (x);
    }  //efp.nextdown(EFP,int)

    //------------------------------------------------------------------------
    //x = x.nextupe ()
    //y = y.nextupe (x)
    //  EFPで表現できる+Inf側の隣接値
    //x = x.nextupd ()
    //y = y.nextupd (x)
    //  doubleで表現できるxよりも大きい最小の値
    //x = x.nextupf ()
    //y = y.nextupf (x)
    //  floatで表現できるxよりも大きい最小の値
    //x = x.nextupx ()
    //y = y.nextupx (x)
    //  extendedで表現できるxよりも大きい最小の値
    //x = x.nextupy ()
    //y = y.nextupy (x)
    //  tripleで表現できるxよりも大きい最小の値
    //x = x.nextup (prec)
    //y = y.nextup (x, prec)
    //  precの精度で表現できるxよりも大きい最小の値
    //
    //  nextup(±0)=正の最小値
    //  nextup(-Inf)=最小値
    //  nextup(+Inf)=+Inf
    //  nextup(NaN)=NaN
    //  nextup(最大値)=+Inf
    //
    public final EFP nextupe () {
      return this.nextupe (this);
    }  //efp.nextupe()
    public final EFP nextupe (EFP x) {
      int xf = x.flg;
      int xe = x.epp;
      long xd = x.dvl;
      long xc = x.cvl;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        if (xf << 1 < 0) {  //±0
          xf = P;  //正の最小値
          xe = -32768;
          xd = MSB;
          xc = 0L;
        } else if (xf == (M | I)) {  //-Inf
          xf = M;  //最小値
          xe = 32767;
          xd = -1L;
          xc = -1L << 128 - LEN;
        }
        //+Inf,NaNはそのまま
      } else if (xf >= 0) {  //+x
        if (xc != -1L << 128 - LEN) {
          xc += (1L << 128 - LEN);  //最下位bitに1を加える
        } else if (xd != -1L) {
          xc = 0L;
          xd++;
        } else if (xe < 32767) {
          xc = 0L;
          xd = MSB;
          xe++;
        } else {  //オーバーフロー
          epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
          epbExceptionOperandExponent = xf;
          epbExceptionOperandMantissa = xd;
          return this.setinf ();  //+Inf
        }
      } else {  //-x
        if (xc != 0L) {
          xc -= 1L << 128 - LEN;  //最下位bitから1を引く
        } else if (xd != MSB) {
          xc = -1L << 128 - LEN;
          xd--;
        } else if (xe > -32768) {
          xc = -1L << 128 - LEN;
          xd = -1L;
          xe--;
        } else {  //アンダーフロー
          epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
          epbExceptionOperandExponent = xf;
          epbExceptionOperandMantissa = xd;
          return this.negset0 ();  //-0
        }
      }
      this.flg = xf;
      this.epp = xe;
      this.dvl = xd;
      this.cvl = xc;
      return this;
    }  //efp.nextupe(EFP)
    public final EFP nextupd () {
      return this.nextupe (this).roundd (EPB_MODE_RP);
    }  //efp.nextupd()
    public final EFP nextupd (EFP x) {
      return this.nextupe (x).roundd (EPB_MODE_RP);
    }  //efp.nextupd(EFP)
    public final EFP nextupf () {
      return this.nextupe (this).roundf (EPB_MODE_RP);
    }  //efp.nextupf()
    public final EFP nextupf (EFP x) {
      return this.nextupe (x).roundf (EPB_MODE_RP);
    }  //efp.nextupf(EFP)
    public final EFP nextupg () {
      return this.nextupe (this).roundg (EPB_MODE_RP);
    }  //efp.nextupg()
    public final EFP nextupg (EFP x) {
      return this.nextupe (x).roundg (EPB_MODE_RP);
    }  //efp.nextupg(EFP)
    public final EFP nextupx () {
      return this.nextupe (this).roundx (EPB_MODE_RP);
    }  //efp.nextupx()
    public final EFP nextupx (EFP x) {
      return this.nextupe (x).roundx (EPB_MODE_RP);
    }  //efp.nextupx(EFP)
    public final EFP nextupy () {
      return this.nextupe (this).roundy (EPB_MODE_RP);
    }  //efp.nextupy()
    public final EFP nextupy (EFP x) {
      return this.nextupe (x).roundy (EPB_MODE_RP);
    }  //efp.nextupy(EFP)
    public final EFP nextup (int prec) {
      switch (prec) {
      case EPB_PREC_EXD:
        return this.nextupe (this).roundx (EPB_MODE_RP);
      case EPB_PREC_SGL:
        return this.nextupe (this).roundf (EPB_MODE_RP);
      case EPB_PREC_DBL:
      case EPB_PREC_DBL3:
        return this.nextupe (this).roundd (EPB_MODE_RP);
      case EPB_PREC_TPL:
        return this.nextupe (this).roundy (EPB_MODE_RP);
      case EPB_PREC_XSG:
        return this.nextupe (this).roundg (EPB_MODE_RP);
      }
      return this.nextupe (this);
    }  //efp.nextup(int)
    public final EFP nextup (EFP x, int prec) {
      switch (prec) {
      case EPB_PREC_EXD:
        return this.nextupe (x).roundx (EPB_MODE_RP);
      case EPB_PREC_SGL:
        return this.nextupe (x).roundf (EPB_MODE_RP);
      case EPB_PREC_DBL:
      case EPB_PREC_DBL3:
        return this.nextupe (x).roundd (EPB_MODE_RP);
      case EPB_PREC_TPL:
        return this.nextupe (x).roundy (EPB_MODE_RP);
      case EPB_PREC_XSG:
        return this.nextupe (x).roundg (EPB_MODE_RP);
      }
      return this.nextupe (x);
    }  //efp.nextup(EFP,int)

    //------------------------------------------------------------------------
    //y = y.parse (s)
    //  文字列解析
    //
    //    仮数部がInfで始まっているときはInf、Inf以外で仮数部に数字がないときはNaNとみなす
    //    仮数部が0bで始まっているときは2進数、0oで始まっているときは8進数、0xで始まっているときは16進数、それ以外は10進数とみなす
    //    0で始まっているだけでは8進数とみなさない
    //    2進数と8進数と16進数は2の累乗の指数部をp~で、10進数は10の累乗の指数部をe~で指定できる
    //    Inf、16進数のa~f、指数部のp~とe~は大文字と小文字を区別しない
    //    後ろのゴミは無視する
    //    先頭に空白があるときはエラーとなってNaNが返ることに注意
    //
    public final EFP parse (String s) {
      int i = 0;
      int l = s.length ();
      char c = i < l ? s.charAt (i++) : '\0';
      //符号
      int f;
      if (c == '-') {
        f = M;
        c = i < l ? s.charAt (i++) : '\0';
      } else {
        f = P;
        if (c == '+') {
          c = i < l ? s.charAt (i++) : '\0';
        }
      }
      //Inf
      if (i + 1 < l && (c | 0x20) == 'i' && (s.charAt (i) | 0x20) == 'n' && (s.charAt (i + 1) | 0x20) == 'f') {
        this.flg = f | I;
        return this;
      }
      //仮数部
      this.inner ();
      this.flg = P | Z;  //符号は最後に付ける
      boolean nan = true;  //true=仮数部に数字がない
      //基数
      int r = 10;
      if (c == '$') {  //16進数
        c = i < l ? s.charAt (i++) : '\0';
        r = 16;
      } else if (c == '@') {  //8進数
        c = i < l ? s.charAt (i++) : '\0';
        r = 8;
      } else if (c == '%') {  //2進数
        c = i < l ? s.charAt (i++) : '\0';
        r = 2;
      } else if (c == '0') {
        nan = false;  //0xの後に数字がなくても0があるのでNaNではなくて0にする
        c = i < l ? s.charAt (i++) : '\0';
        if ((c | 0x20) == 'x') {  //16進数
          c = i < l ? s.charAt (i++) : '\0';
          r = 16;
        } else if ((c | 0x20) == 'o') {  //8進数
          c = i < l ? s.charAt (i++) : '\0';
          r = 8;
        } else if ((c | 0x20) == 'b') {  //2進数
          c = i < l ? s.charAt (i++) : '\0';
          r = 2;
        }
      }
      //整数部
      {
        int t = Character.digit (c, r);
        if (t >= 0) {
          nan = false;
          do {
            this.imul (EFP_DIGIT[r]).iadd (EFP_DIGIT[t]);
            c = i < l ? s.charAt (i++) : '\0';
            t = Character.digit (c, r);
          } while (t >= 0);
        }
      }
      //小数部
      int o = 0;  //-小数点以下の桁数またはbit数
      if (c == '.') {
        c = i < l ? s.charAt (i++) : '\0';
        int t = Character.digit (c, r);
        if (t >= 0) {
          nan = false;
          do {
            o--;
            this.imul (EFP_DIGIT[r]).iadd (EFP_DIGIT[t]);
            c = i < l ? s.charAt (i++) : '\0';
            t = Character.digit (c, r);
          } while (t >= 0);
          if (r == 8) {  //8進数のときは1桁が3bit
            o *= 3;
          } else if (r == 16) {  //16進数のときは1桁が4bit
            o <<= 2;
          }
        }
      }
      //NaN
      if (nan) {  //仮数部に数字がない
        this.flg = N;
        return this.outer ();
      }
      //0
      if (this.flg << 1 < 0) {  //Z
        this.flg = f | Z;
        return this.outer ();
      }
      //指数部
      if ((c | 0x20) == (r == 10 ? 'e' : 'p')) {
        c = i < l ? s.charAt (i++) : '\0';
        int m;  //指数部の符号
        if (c == '-') {
          m = -1;
          c = i < l ? s.charAt (i++) : '\0';
        } else {
          m = 1;
          if (c == '+') {
            c = i < l ? s.charAt (i++) : '\0';
          }
        }
        if ('0' <= c && c <= '9') {  //指数部は常に10進数
          int t = 0;
          do {
            t = t * 10 + (c - '0');
            if (t >= 100000000) {  //オーバーフローまたはアンダーフロー
              this.outer ();
              if (m >= 0) {  //オーバーフロー
                //0e+999999999は0だが0は除外済み
                epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
                epbExceptionOperandExponent = 0;
                epbExceptionOperandMantissa = 0L;
                return this.sete (OVFL_RESULTS[epbRoundingPrec << 3 | epbRoundingMode << 1 | f >>> 31]).finish ();  //±Inf
              } else {  //アンダーフロー
                //1e-999999999は0
                epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
                epbExceptionOperandExponent = 0;
                epbExceptionOperandMantissa = 0L;
                return this.sete (UNFL_RESULTS[epbRoundingPrec << 3 | epbRoundingMode << 1 | f >>> 31]).finish ();  //±0
              }
            }
            c = i < l ? s.charAt (i++) : '\0';
          } while ('0' <= c && c <= '9');
          o += m * t;  //指数部-小数点以下の桁数
        }
      }
      if (r != 10) {  //2^oを掛ける
        this.shl (o);  //8進数または16進数のときも指数部はbit単位
      } else if (o > 0) {  //10^oを掛ける
        //this.imul (new EFP (TEN).pow (o));
        EFP t = new EFP (ONE);
        for (int j = 0, m = o; m != 0; j++, m >>>= 1) {
          if ((m & 1) != 0) {
            t.imul (EFP_TEN_POWER_P[j]);
          }
        }
        this.imul (t);
      } else if (o < 0) {  //10^-oで割る
        //this.div (new EFP (TEN).pow (-o));
        EFP t = new EFP (ONE);
        for (int j = 0, m = -o; m != 0; j++, m >>>= 1) {
          if ((m & 1) != 0) {
            t.imul (EFP_TEN_POWER_P[j]);
          }
        }
        this.div (t);
      }
      //符号
      return this.outer ().neg (f < 0);
    }  //efp.parse(String)

    //------------------------------------------------------------------------
    //x = x.pow (y)
    //  x=x^y
    //z = z.pow (x, y)
    //  z=x^y
    //  累乗
    //
    //  指数関数との関係
    //    x^y=(e^(log(x)))^y
    //       =e^(log(x)*y)
    //       =(2^(log2(x)))^y
    //       =2^(log2(x)*y)
    //
    //  メモ
    //    log2(x)はxが0に近すぎると-Infになってしまう
    //    x=2^k*v
    //    log2(2^k*v)=k+log2(v)
    //    x^y=2^(log2(x)*y)
    //       =2^(log2(2^k*v)*y)
    //       =2^((k+log2(v))*y)
    //       =2^(k*y+log2(v)*y)
    //       =2^(k*y)*2^(log2(v)*y)
    //
    public final EFP pow (EFP y) {
      return this.pow (this, y);
    }  //efp.pow(EFP)
    public final EFP pow (EFP x, EFP y) {
      int xf = x.flg;
      int yf = y.flg;
      if (yf << 1 != 0) {  //yが±0,±Inf,NaN
        if (yf << 1 < 0) {
          this.flg = P;  //x^±0=1。NaN^±0=1を含む
          this.epp = 0;
          this.dvl = MSB;
          this.cvl = 0L;
          return this;
        } else {
          int s;
          this.flg = (yf << 3 < 0 ||  //x^NaN=NaN
                      xf << 3 < 0 ||  //NaN^(y!=±0)=NaN
                      (s = x.cmp1abs ()) == 0 ? N :  //(|x|==1)^±Inf=NaN
                      (s ^ yf) >= 0 ? P | I :  //(|x|>1)^+Inf=(|x|<1)^-Inf=+Inf。±Inf^±Inf=+Infを含む
                      P | Z);  //(|x|>1)^-Inf=(|x|<1)^+Inf=+0。±Inf^∓Inf=+0を含む
          return this;
        }
      } else if (xf << 1 != 0) {  //xが±0,±Inf,NaNでyが±0,±Inf,NaN以外
        this.flg = (xf << 3 < 0 ? N :  //NaN^(y!=±0)=NaN
                    xf >= 0 ?  //xが+0,+Inf
                    (xf << 2 ^ yf) >= 0 ? P | Z :  //+0^(y>0)=+0,+Inf^(y<0)=+0
                    P | I :  //+0^(y<0)=+Inf,+Inf^(y>0)=+Inf
                    //xが-0,-Inf
                    y.isodd () ?  //yが奇数
                    (xf << 2 ^ yf) >= 0 ? M | Z :  //-0^(y>0 and is odd)=-0,-Inf^(y<0 and is odd)=-0
                    M | I :  //-0^(y<0 and is odd)=-Inf,-0^(y<0 and is odd)=-Inf
                    //yが奇数でない(偶数であるまたは整数でない)
                    //!!! (-Inf)^-1.5は+0なのか?
                    //  System.out.println(Math.pow(Double.NEGATIVE_INFINITY,-1.5));
                    //  0.0
                    (xf << 2 ^ yf) >= 0 ? P | Z :  //-0^(y>0 and is not odd)=+0,-Inf^(y<0 and is even)=+0
                    P | I);  //-0^(y<0 and is even)=+Inf,-Inf^(y>0 and is even)=+Inf
        return this;
      } else if (xf < 0) {  //両方±0,±Inf,NaN以外でxが負
        this.inner ();
        if (y.iseven ()) {  //yが偶数
          EFP w = new EFP ();
          this.imulw (w, new EFP ().ineg (x).log2 (), y);
          if (this.epp >= 16) {  //指数が大きすぎる
            this.flg = this.flg >= 0 ? P | I : P | Z;  //2^+big=+Inf,2^-big=+0
            return this.outer ();
          } else {
            int k = this.geti ();
            return this.frac ().iadd (w).exp2 ().outer ().shl (k);
          }
        } else if (y.isodd ()) {  //yが奇数
          EFP w = new EFP ();
          this.imulw (w, new EFP ().ineg (x).log2 (), y);
          if (this.epp >= 16) {  //指数が大きすぎる
            this.flg = this.flg >= 0 ? M | I : M | Z;  //-(2^+big)=-Inf,-(2^-big)=-0
            return this.outer ();
          } else {
            int k = this.geti ();
            return this.frac ().iadd (w).exp2 ().shl (k).outer ().neg ();
          }
        } else {  //yが整数でない
          this.flg = N;  //(x<0)^(y is not integer)=NaN
          return this.outer ();
        }
      } else {  //両方±0,±Inf,NaN以外でxが正
        this.inner ();
        EFP w = new EFP ();
        this.imulw (w, new EFP ().log2 (x), y);
        if (this.epp >= 16) {  //指数が大きすぎる
          this.flg = this.flg >= 0 ? P | I : P | Z;  //2^+big=+Inf,2^-big=+0
          return this.outer ();
        } else {
          int k = this.geti ();
          return this.frac ().iadd (w).exp2 ().outer ().shl (k);
        }
      }
    }  //efp.pow(EFP,EFP)

    //------------------------------------------------------------------------
    //x = x.powi (n)
    //  x=x^n
    //z = z.powi (x, n)
    //  z=x^n
    //  int累乗
    //
    public final EFP powi (int n) {
      return this.powi (this, n);
    }  //efp.powi(int)
    public final EFP powi (EFP x, int n) {
      int xf = x.flg;
      if (n == 0) {  //yが±0,±Inf,NaN
        //this.set1 ();
        this.flg = P;  //x^±0=1。NaN^±0=1を含む
        this.epp = 0;
        this.dvl = MSB;
        this.cvl = 0L;
        return this;
      } else if (xf << 1 != 0) {  //xが±0,±Inf,NaNでyが±0,±Inf,NaN以外
        this.flg = (xf << 3 < 0 ? N :  //NaN^(y!=±0)=NaN
                    xf >= 0 ?  //xが+0,+Inf
                    (xf << 2 ^ n) >= 0 ? P | Z :  //+0^(y>0)=+0,+Inf^(y<0)=+0
                    P | I :  //+0^(y<0)=+Inf,+Inf^(y>0)=+Inf
                    //xが-0,-Inf
                    (n & 1) != 0 ?  //yが奇数
                    (xf << 2 ^ n) >= 0 ? M | Z :  //-0^(y>0 and is odd)=-0,-Inf^(y<0 and is odd)=-0
                    M | I :  //-0^(y<0 and is odd)=-Inf,-0^(y<0 and is odd)=-Inf
                    //yが奇数でない(偶数であるまたは整数でない)
                    //!!! (-Inf)^-1.5は+0なのか?
                    //  System.out.println(Math.pow(Double.NEGATIVE_INFINITY,-1.5));
                    //  0.0
                    (xf << 2 ^ n) >= 0 ? P | Z :  //-0^(y>0 and is not odd)=+0,-Inf^(y<0 and is even)=+0
                    P | I);  //-0^(y<0 and is even)=+Inf,-Inf^(y>0 and is even)=+Inf
        return this;
      } else {  //両方±0,±Inf,NaN以外
        //  y==0は処理済み
        int t = n >= 0 ? n : -n;  //|y|
        if (t >>> 16 != 0) {  //t==0x80000000の場合があるのでt>65535は不可
          //|x|が1に近くて|n|が大きいとき乗算を繰り返す方法では誤差が大きくなるのでpowに計算させる
          int xe = x.epp;
          long xd = x.dvl;
          if (xe == 0 && xd >>> -16 == 0x8000L ||
              xe == -1 && xd >>> -16 == 0xffffL) {  //±1±ε
            return this.pow (x, new EFP (n));
          }
        }
        this.inner ();
        EFP w = new EFP (x);  //x^(2^0)
        if ((t & 1) == 0) {
          //this.set1 ();
          this.flg = P;  //x^0=1
          this.epp = 0;
          this.dvl = MSB;
          this.cvl = 0L;
        } else {
          //this.sete (x);
          this.flg = xf;  //x^1=x
          this.epp = x.epp;
          this.dvl = x.dvl;
          this.cvl = x.cvl;
        }
        while ((t >>>= 1) != 0) {
          w.squ ();  //x^(2^k)。指数部分が32bitでも足りなくなることがあるのでisquは不可
          if ((t & 1) != 0) {
            this.mul (w);
          }
        }
        if (n < 0) {  //x^(y<0)=1/x^-y
          this.rcp ();
        }
        return this.outer ().finish ();
      }
    }  //efp.powi(EFP,int)

    //------------------------------------------------------------------------
    //x = x.quo (y)
    //  x=trunc(x/y)
    //z = z.quo (x, y)
    //  z=trunc(x/y)
    //  商
    //
    public final EFP quo (EFP y) {
      return this.quo (this, y);
    }  //efp.quo(EFP)
    public final EFP quo (EFP x, EFP y) {
      int xf = x.flg;
      int yf = y.flg;
      if ((xf | yf) << 1 != 0) {  //どちらかが±0,±Inf,NaN
        this.flg = ((xf | yf) << 3 != 0 || (xf & yf & (Z | I)) != 0 ? N :  //どちらかがNaNまたは±0/±0または±Inf/±InfのときNaN
                    (xf ^ yf) & M | ((xf & Z | yf & I) != 0 ? Z : I));  //±0/(±0,NaN以外)または(±Inf,NaN以外)/±Infのとき±0、(±0,NaN以外)/±0または±Inf/(±Inf,NaN以外)のとき±Inf
        return this;
      }
      //±0,±Inf,NaN以外
      int zf = xf ^ yf;  //符号が同じならばP、異なればM。ここでセットされるのはMだけ
      int ze = x.epp - y.epp;  //商の小数点はq0の左端から右にzeの位置
      if (ze < 0) {  //|x|<|y|。商は0
        this.flg = zf | Z;
        return this;
      }
      //仮数部を31bitずつ3分割する
      long r01 = x.dvl;
      long y01 = y.dvl;
      long r2 = (r01 << -2 | x.cvl >>> 2) >>> 33;
      long y2 = (y01 << -2 | y.cvl >>> 2) >>> 33;
      r01 >>>= 2;
      y01 >>>= 2;
      long y0 = y01 >>> 31;
      long y1 = y01 & 0x7fffffffL;
      //先頭1bit
      boolean qq;
      if (r01 < y01 || (r01 == y01 && r2 < y2)) {  //xの仮数部<yの仮数部
        if (ze == 0) {  //|x|<|y|。商は0
          this.flg = zf | Z;
          return this;
        }
        qq = false;
      } else {
        qq = true;
        r2 -= y2;
        r01 -= y01;
        if (r2 < 0L) {
          r2 += 0x80000000L;
          r01--;
        }
      }
      long q0, q1, q2;
      //1桁目
      q0 = r01 >> 31 == y0 ? 0x7fffffffL : r01 / y0;
      r01 = (r01 - q0 * y0 << 31) + r2 - q0 * y1;
      if (r01 < 0L) {
        q0--;
        r01 += y01;
      }
      r2 = q0 * y2 + 0x7fffffffL;
      r01 -= r2 >> 31;
      r2 = ~r2 & 0x7fffffffL;  //~(r2 | ~0x7fffffffL)
      if (r01 < 0L) {
        q0--;
        r2 += y2;
        r01 += y01 + (r2 >> 31);
        r2 &= 0x7fffffffL;
      }
      if (ze <= 31) {
        q0 &= ~0x7fffffffL >> ze;
        q1 = q2 = 0L;
      } else {
        //2桁目
        q1 = r01 >> 31 == y0 ? 0x7fffffffL : r01 / y0;
        r01 = (r01 - q1 * y0 << 31) + r2 - q1 * y1;
        if (r01 < 0L) {
          q1--;
          r01 += y01;
        }
        r2 = q1 * y2 + 0x7fffffffL;
        r01 -= r2 >> 31;
        r2 = ~r2 & 0x7fffffffL;  //~(r2 | ~0x7fffffffL)
        if (r01 < 0L) {
          q1--;
          r2 += y2;
          r01 += y01 + (r2 >> 31);
          r2 &= 0x7fffffffL;
        }
        if (ze <= 62) {
          q1 &= ~0x7fffffffL >> ze - 31;
          q2 = 0L;
        } else {
          //3桁目
          q2 = r01 >> 31 == y0 ? 0x7fffffffL : r01 / y0;
          r01 = (r01 - q2 * y0 << 31) + r2 - q2 * y1;
          if (r01 < 0L) {
            q2--;
            r01 += y01;
          }
          r2 = q2 * y2 + 0x7fffffffL;
          r01 -= r2 >> 31;
          r2 = ~r2 & 0x7fffffffL;  //~(r2 | ~0x7fffffffL)
          if (r01 < 0L) {
            q2--;
            //r2 += y2;
            //r01 += y01 + (r2 >> 31);
            //r2 &= 0x7fffffffL;
          }
          if (ze <= 93) {
            q2 &= ~0x7fffffffL >> ze - 62;
          }
        }
      }
      //商  (((qq ? 1 : 0) << 31 | q0) << 31 | q1) << 31 | q2
      //正規化する
      if (qq) {  //商は94bit
        q0 = MSB | q0 << 32 | q1 << 1 | q2 >>> 30;
        q2 <<= -30;
      } else {  //商は93bit
        ze--;
        q0 = q0 << -31 | q1 << 2 | q2 >>> 29;
        q2 <<= -29;
      }
      return this.finish (zf, ze, q0, q2, 0L);
    }  //efp.quo(EFP,EFP)

    //------------------------------------------------------------------------
    //x = x.rad ()
    //  x*=pi/180
    //y = y.rad (x)
    //  y=x*pi/180
    //  pi/180倍(ラジアン)
    //
    //  グラフ
    //    perl -e "use Graph;$g=new Graph();$g->grid();$g->func(sub{atan2(1,1)/45*$_[0]});print$g"
    //    echo read("../misc/efp.gp");eval("rad(x)=x*(Pi/180)");graph(rad) | gp -q
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    *********************************************************************************
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //
    public final EFP rad () {
      return this.mul (this, TO_RAD);  //x*pi/180
    }  //efp.rad()
    public final EFP rad (EFP x) {
      return this.mul (x, TO_RAD);  //x*pi/180
    }  //efp.rad(EFP)

    //------------------------------------------------------------------------
    //y = y.random ()
    //  y=random()
    //  乱数
    //
    //  0以上1未満の乱数
    //  0以上1未満の1/2^LENの倍数がほぼ一様に出現するはず
    //  指数部が小さい数は有効桁数が少ない
    //
    public final EFP random () {
      int xf = P;
      int xe = -1;
      long xd = epbRand48 ();
      long xc = epbRand48 ();
      xd = xd << 16 | xc >>> 32;
      xc = xc << 32 & -LSB;
      if (xd != 0L) {
        int o = Long.numberOfLeadingZeros (xd);
        if (o > 0) {
          xe -= o;
          xd = xd << o | xc >>> -o;
          xc <<= o;
        }
      } else if (xc != 0L) {
        int o = Long.numberOfLeadingZeros (xc);
        xe -= 64 + o;
        xd = xc << o;
        xc = 0L;
      } else {
        xf = P | Z;
      }
      return this.finish (xf, xe, xd, xc, 0L);
    }  //efp.random()

    //------------------------------------------------------------------------
    //x = x.rcp ()
    //  x=1/x
    //y = y.rcp (x)
    //  y=1/x
    //  逆数 reciprocal
    //
    //  グラフ
    //    perl -e "use Graph;$g=new Graph();$g->grid();$g->func(sub{1/$_[0]});print$g"
    //    echo read("../misc/efp.gp");eval("rcp(x)=1/x");graph(rcp) | gp -q
    //    +---------+---------+---------+---------+-**------+---------+---------+---------+
    //    |                                       |  *                                    |
    //    |                                       |  *                                    |
    //    |                                       |  *                                    |
    //    |                                       |  *                                    |
    //    +                                       +  *                                    +
    //    |                                       |  **                                   |
    //    |                                       |   *                                   |
    //    |                                       |   *                                   |
    //    |                                       |   **                                  |
    //    +                                       +    *                                  +
    //    |                                       |    **                                 |
    //    |                                       |     **                                |
    //    |                                       |      **                               |
    //    |                                       |       **                              |
    //    +                                       +        ***                            +
    //    |                                       |          ****                         |
    //    |                                       |             *******                   |
    //    |                                       |                   **************      |
    //    |                                       |                                ********
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //    ********                                |                                       |
    //    |      **************                   |                                       |
    //    |                   *******             |                                       |
    //    |                         ****          |                                       |
    //    +                            ***        +                                       +
    //    |                              **       |                                       |
    //    |                               **      |                                       |
    //    |                                **     |                                       |
    //    |                                 **    |                                       |
    //    +                                  *    +                                       +
    //    |                                  **   |                                       |
    //    |                                   *   |                                       |
    //    |                                   *   |                                       |
    //    |                                   **  |                                       |
    //    +                                    *  +                                       +
    //    |                                    *  |                                       |
    //    |                                    *  |                                       |
    //    |                                    *  |                                       |
    //    |                                    *  |                                       |
    //    +---------+---------+---------+------**-+---------+---------+---------+---------+
    //
    //  ニュートン法
    //    f(x)=a-1/x
    //    f'(x)=1/x^2
    //    x'=x-f(x)/f'(x)
    //      =x-(a-1/x)/(1/x^2)
    //      =x-(a*x^2-x)
    //      =2*x-a*x^2
    //
    public final EFP rcp () {
      return this.div (ONE, this);
    }  //efp.rcp()
    public final EFP rcp (EFP x) {
      if (false) {  //1を割る。[93] 55.7ns。正確だが遅い
        return this.div (ONE, x);
      } else {  //ニュートン法。[91] 37.0ns。速いが誤差が大きい
        int xf = x.flg;
        if (xf << 1 != 0) {  //±0,±Inf,NaN
          if (xf << 1 < 0) {  //±0
            epbFpsr |= EPB_FPSR_DZ;
            epbExceptionOperandExponent = xf & M;
            epbExceptionOperandMantissa = 0x0000000000000000L;
            this.flg = xf ^ (Z | I);  //1/±0=±Inf
          } else if (xf << 2 < 0) {  //±Inf
            this.flg = xf ^ (Z | I);  //1/±Inf=±0
          } else {  //NaN
            this.flg = N;
          }
          return this;
        }
        //±0,±Inf,NaN以外
        this.inner ();
        long s = Double.doubleToLongBits (1.0 / Double.longBitsToDouble ((long) 1023 << 52 | x.dvl << 1 >>> 12));
        EFP t = new EFP (xf, (int) (s >>> 52) - 1023 - x.epp, MSB | s << 12 >>> 1, 0L);
        //return this.imul (x, t).negsub (TWO).outer ().mul (t);  //(2-x*t)*t。[91] 38.4ns
        this.imul2 (t);  //2*t
        t.isqu ().imul (x);  //x*t^2
        return this.outer ().sub (t);  //2*t-x*t^2。[91] 37.0ns。mulがsquになっている分速い
      }
    }  //efp.rcp(EFP)

    //------------------------------------------------------------------------
    //x = x.rcpdiv (y)
    //  x=y/x
    //  逆除算
    //
    //  x.div(y).rcp()と同じ
    //  z.rcpdiv(x,y)はz.div(y,x)と同じ
    //
    public final EFP rcpdiv (EFP y) {
      return this.div (y, this);
    }  //efp.rcpdiv(EFP)
    public final EFP rcpdiv (EFP x, EFP y) {
      return this.div (y, x);
    }  //efp.rcpdiv(EFP,EFP)

    //------------------------------------------------------------------------
    //x = x.rem (y)
    //  x%=y
    //z = z.rem (x, y)
    //  z=x%y
    //  剰余(round-to-zero)
    //
    //  x%y=x-trunc(x/y)*y
    //  (xn/xd)-trunc(x/y)*(yn/yd)
    //    =(xn/xd)-((trunc(x/y)*yn)/yd)
    //    =(xn*yd-xd*((trunc(x/y)*yn))/(xd*yd)
    //
    //  Javaのx%yと同じ
    //    x%y=x-(x/y)*y
    //       =isNaN(x)||isNaN(y)||isInfinite(x)?NaN:isInfinite(y)?x:(t=x-trunc(x/y)*y)==0?copySign(0,x):t
    //    Javaの%演算子はdoubleをdoubleのまま計算する
    //  被除数から0の方向にある最も近い除数の倍数を引いた結果を返す
    //  倍数の符号は任意なので除数の符号は結果に影響しない
    //     5.0 %  3.0 ==  5.0 - (long) ( 5.0 /  3.0) *  3.0 ==  2.0
    //     5.0 % -3.0 ==  5.0 - (long) ( 5.0 / -3.0) * -3.0 ==  2.0
    //    -5.0 %  3.0 == -5.0 - (long) (-5.0 /  3.0) *  3.0 == -2.0
    //    -5.0 % -3.0 == -5.0 - (long) (-5.0 / -3.0) * -3.0 == -2.0
    //  z  余り remainder
    //  x  被除数 dividend
    //  y  除数 divisor
    //
    public final EFP rem (EFP y) {
      return this.rem (this, y);
    }  //efp.rem(EFP)
    public final EFP rem (EFP x, EFP y) {
      int xf = x.flg;
      int yf = y.flg;
      epbFpsr &= 0xff00ffff;  //quotient byteをクリアする
      if ((xf | yf) << 1 != 0) {  //どちらかが±0,±Inf,NaN
        if ((xf | yf) << 3 < 0) {  //rem(NaN,y)=NaN, rem(x,NaN)=NaN
          this.flg = N;
        } else if (xf << 2 < 0 ||  //rem(±Inf,y)=NaN
                   yf << 1 < 0) {  //rem(x,±0)=NaN
          //除数が±0でもゼロ除算にはならない
          epbFpsr |= EPB_FPSR_OE;
          if (yf << 1 < 0) {  //±0
            epbExceptionOperandExponent = yf & M;
            epbExceptionOperandMantissa = 0x0000000000000000L;
          } else if (yf << 2 < 0) {  //±Inf
            epbExceptionOperandExponent = yf & M | 0x7fff << 16;
            epbExceptionOperandMantissa = 0x0000000000000000L;
          } else {  //±y
            epbExceptionOperandExponent = yf & M | 0x3fff + y.epp << 16;
            epbExceptionOperandMantissa = y.dvl;
          }
          this.flg = N;
        } else if (xf << 1 < 0) {  //rem(±0,y)=±0
          epbFpsr |= ((xf ^ yf) & M) >>> 8;  //quotient byteに商の符号を入れる
          this.flg = xf;
        } else {  //rem(x,±Inf)=x
          epbFpsr |= ((xf ^ yf) & M) >>> 8;  //quotient byteに商の符号を入れる
          this.finish (xf, x.epp, x.dvl, x.cvl, 0L);  //xが非正規化数のときUFをセットする
        }
        return this;
      }
      //両方±0,±Inf,NaN以外
      epbFpsr |= ((xf ^ yf) & M) >>> 8;  //quotient byteに商の符号を入れる
      if (false) {
        this.inner ();
        //this.sub (x, new EFP ().div (x, y).trunc ().imul (y));  //x-trunc(x/y)*y。this==x||this==yの場合に注意
        int s;
        long t;
        if ((s = x.epp - y.epp) < 0 ||
            s == 0 && ((t = x.dvl - y.dvl) < 0L ||
                       t == 0L && (x.cvl >>> 1) - (y.cvl >>> 1) < 0L)) {  //|x|<|y|。商が0
          //this.sete (x);  //被除数がそのまま余りになる
          this.flg = xf;
          this.epp = x.epp;
          this.dvl = x.dvl;
          this.cvl = x.cvl;
        } else {  //|x|>=|y|。商が0ではない
          EFP xx = x != this ? x : new EFP (x);  //xのコピー
          EFP yy = y != this ? y : new EFP (y);  //yのコピー
          this.divrz (xx, yy).trunc ();  //trunc(x/y)。商。divを使うと丸め(RN)で商の絶対値が1大きくなってしまうことがあるのでdivrzを使う
          epbQuotient = this.geti32abs ();
          epbFpsr |= (epbQuotient & 127) << 16;  //商の絶対値の下位7bit
          EFP ww = new EFP ();
          this.imulw (ww, this, yy).negsub (xx).sub (ww);  //x-trunc(x/y)*y。余り。xがyの倍数に近いとき桁落ちが発生するので乗算を倍精度で行う
          if (this.flg << 1 < 0) {  //余りが0
            this.flg = xf | Z;  //0にxの符号を付ける
          }
        }
        return this.outer ().finish ();
      } else {
        this.inner ();
        int ye = y.epp;  //this==yの場合があるので順序に注意する
        long yd = y.dvl;
        long yc = y.cvl;
        long yc1 = yc >>> 1;
        this.epp = x.epp;
        this.dvl = x.dvl;
        this.cvl = x.cvl;
        int i;
        long l;
        int q = 0;
        if ((i = this.epp - ye) > 0 ||
            i == 0 && ((l = this.dvl - yd) > 0L ||
                       l == 0L && this.cvl >>> 1 >= yc1)) {  //|x|>=|y|。商は0ではない
          this.flg = P;  //|x|。余りの初期値
          EFP t = new EFP (P, 0, yd, yc);
          do {
            t.epp = i = (l = this.dvl - yd) > 0L || l == 0L && this.cvl >>> 1 >= yc1 ? this.epp : this.epp - 1;  //指数部を揃えて
            if ((i -= ye) <= 31) {
              q |= 1 << i;
            }
            this.sub (t);  //引く。アンダーフローのチェックは後で行う
          } while (this.flg == 0 &&  //0ではない
                   ((i = this.epp - ye) > 0 ||
                    i == 0 && ((l = this.dvl - yd) > 0L ||
                               l == 0L && this.cvl >>> 1 >= yc1)));  //this>=|y|。まだ引ける。指数部が極端に違うと繰り返す回数が大きくなる
          this.flg |= xf;  //余りが0の場合も含めてyの符号に関係なくxの符号を付ける
        } else {  //|x|<|y|。商は0
          this.flg = xf;  //被除数がそのまま余りになる
        }
        epbQuotient = q;
        epbFpsr |= (q & 127) << 16;  //商の絶対値の下位7bit
        return this.outer ().finish ();
      }
    }  //efp.rem(EFP,EFP)

    //------------------------------------------------------------------------
    //x = x.rint ()
    //  x=rint(x)
    //y = y.rint (x)
    //  y=rint(x)
    //  丸め(nearest-even)
    //
    //  グラフ
    //    perl -e "use Graph;$g=new Graph();$g->grid();$g->func(sub{my$x=$_[0];my$t=int$x;my$f=abs($x-$t);$t+($f==0.5&&($t&1)!=0||$f>0.5?$x<=>0:0)});print$g"
    //    echo read("../misc/efp.gp");eval("rint(x)={my(f=floor(x),s=sign(x-floor(x)-0.5));if(s==0&&(f%2==0)||s<0,f,f+1)}");graph(rint) | gp -q
    //    +---------+---------+---------+---------+---------+---------+---------+----******
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                        ***********    +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +              ***********              +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +    ***********                        +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +---------+---------+---------+----***********----+---------+---------+---------+
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                        ***********    +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +              ***********              +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +    ***********                        +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    ******----+---------+---------+---------+---------+---------+---------+---------+
    //
    //  最も近い整数に丸める
    //  小数点以下が0.5のときは偶数の方向に丸める
    //
    public final EFP rint () {
      return this.rint (this);
    }  //efp.rint()
    public final EFP rint (EFP x) {  //4.6ns
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        this.flg = xf;
        return this;
      }
      //±0,±Inf,NaN以外
      int xe = x.epp;
      long xd = x.dvl;
      long xc = x.cvl;
      if (xe < 0) {  //0<|x|<1
        epbFpsr |= EPB_FPSR_X2;  //不正確な結果
        if (xe < -1 || xd == MSB && xc == 0L) {  //0<|x|<=1/2
          this.flg = xf | Z;  //rint(-1/2<=x<0)=-0, rint(0<x<=1/2)=+0
        } else {  //1/2<|x|<1
          this.flg = xf;  //rint(-1<x<-1/2)=-1, rint(1/2<x<1)=1
          this.epp = 0;
          this.dvl = MSB;
          this.cvl = 0L;
        }
        return this;
      }
      //整数部がある
      long m = MSB >> xe;  //整数部のマスク。符号に注意
      if (xe <= 62) {  //0..62。dの途中まで整数部
        if ((xd & ~m | xc) != 0L) {  //小数部が0ではない
          epbFpsr |= EPB_FPSR_X2;  //不正確な結果
          long t = xd;  //保存して
          xd &= m;  //小数部を切り捨てる
          if ((t & -(m >> 1)) != 0L && (t & (-m | ~(m >> 1)) | xc) != 0L) {  //guard bitが1かつLSBまたはguard bit以外の端数が0ではない
            xd -= m;  //絶対値に1を加える。符号に注意
            if (xd >= 0L) {  //dから溢れた
              xd = MSB;
              xe++;
              if ((short) xe != xe) {  //オーバーフローした
                epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
                epbExceptionOperandExponent = xf;
                epbExceptionOperandMantissa = xd;
                return this.sete (OVFL_RESULTS[epbRoundingPrec << 3 | epbRoundingMode << 1 | xf >>> 31]).finish ();  //±Inf
              }
            }
          }
          xc = 0L;
        }
      } else if (xe == 63) {  //63。dの末尾まで整数部
        if (xc != 0L) {  //小数部が0ではない
          epbFpsr |= EPB_FPSR_X2;  //不正確な結果
          if (xc < 0L && (xd << -1 | xc << 1) != 0L) {  //guard bitが1かつLSBまたはguard bit以外の端数が0ではない
            xd++;  //絶対値に1を加える
            if (xd >= 0L) {  //dから溢れた
              xd = MSB;
              xe++;
              if ((short) xe != xe) {  //オーバーフローした
                epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
                epbExceptionOperandExponent = xf;
                epbExceptionOperandMantissa = xd;
                return this.sete (OVFL_RESULTS[epbRoundingPrec << 3 | epbRoundingMode << 1 | xf >>> 31]).finish ();  //±Inf
              }
            }
          }
          xc = 0L;
        }
      } else if (xe <= LEN - 2) {  //64..90。cの途中まで整数部
        if ((xc & ~m) != 0L) {  //小数部が0ではない
          epbFpsr |= EPB_FPSR_X2;  //不正確な結果
          long t = xc;  //保存して
          xc &= m;  //小数部を切り捨てる
          if ((t & -(m >> 1)) != 0L && (t & (-m | ~(m >> 1))) != 0L) {  //guard bitが1かつLSBまたはguard bit以外の端数が0ではない
            xc -= m;  //絶対値に1を加える。符号に注意
            if ((t ^ xc) < 0L) {  //cから溢れた
              xd++;
              if (xd >= 0L) {  //dから溢れた
                xd = MSB;
                xe++;
                if ((short) xe != xe) {  //オーバーフローした
                  epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
                  epbExceptionOperandExponent = xf;
                  epbExceptionOperandMantissa = xd;
                  return this.sete (OVFL_RESULTS[epbRoundingPrec << 3 | epbRoundingMode << 1 | xf >>> 31]).finish ();  //±Inf
                }
              }
            }
          }
        }
      }
      //すべて整数部のときはそのまま
      return finish (xf, xe, xd, xc, 0L);
    }  //efp.rint(EFP)

    //------------------------------------------------------------------------
    //x = x.round ()
    //x = x.round (roundingMode)
    //x = x.round (x)
    //x = x.round (x, roundingMode)
    //  丸め
    //
    //  サイズの制限を与えずに整数に丸める
    //
    public final EFP round () {
      return this.round (this, EPB_MODE_RN);
    }  //efp.round()
    public final EFP round (int roundingMode) {
      return this.round (this, roundingMode);
    }  //efp.round(int)
    public final EFP round (EFP x) {
      return this.round (x, EPB_MODE_RN);
    }  //efp.round(EFP)
    public final EFP round (EFP x, int roundingMode) {
      return (roundingMode == EPB_MODE_RN ? this.rint (x) :
              roundingMode == EPB_MODE_RM ? this.floor (x) :
              roundingMode == EPB_MODE_RP ? this.ceil (x) :
              this.trunc (x));
    }  //efp.round(EFP,int)

    //------------------------------------------------------------------------
    //x = x.roundd ()
    //x = x.roundd (roundingMode)
    //x = x.roundd (x)
    //x = x.roundd (x, roundingMode)
    //  double丸め
    //
    //  この関数はepbRoundingModeとepbRoundingPrecを無視する
    //  double(指数部11bit,仮数部52+1bit,非正規化数を含む)で表現できる値に丸める
    //  doubleで表現できないときは±Infに変換する
    //
    public final EFP roundd () {
      return this.roundd (this, EPB_MODE_RN);
    }  //efp.roundd()
    public final EFP roundd (int roundingMode) {
      return this.roundd (this, roundingMode);
    }  //efp.roundd(int)
    public final EFP roundd (EFP x) {
      return this.roundd (x, EPB_MODE_RN);
    }  //efp.roundd(EFP)
    public final EFP roundd (EFP x, int roundingMode) {
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        this.flg = xf;
        return this;
      }
      //±0,±Inf,NaN以外
      int xe = x.epp;  //正規化数は-1022<=xe<=1023、非正規化数は-1075<=xe<=-1023
      long xd = x.dvl;
      long xc = x.cvl;
      if (xe < -1075) {  //指数部が小さすぎる。非正規化数の最小値は2^-1074だが丸めで繰り上がる場合があるので一旦2^-1075まで受け入れる
        epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
        epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
        epbExceptionOperandMantissa = xd;
        return this.sete (UNFL_RESULTS[EPB_PREC_DBL << 3 | roundingMode << 1 | xf >>> 31]);  //±0
      }
      if (1023 < xe) {  //指数部が大きすぎる
        if (true) {
          epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
          if ((xd << 53 | xc) != 0L) {  //端数が0ではない
            epbFpsr |= EPB_FPSR_X2;  //不正確な結果
          }
        } else {
          epbFpsr |= EPB_FPSR_OF | EPB_FPSR_X2;  //オーバーフロー、不正確な結果
        }
        epbExceptionOperandExponent = xf | 0x3fff - 0x6000 + xe << 16;
        epbExceptionOperandMantissa = xd;
        return this.sete (OVFL_RESULTS[EPB_PREC_DBL << 3 | roundingMode << 1 | xf >>> 31]);  //±Inf
      }
      long xb = 0L;
      int o = xe <= -1023 ? 11 + -1022 - xe : 11;  //右にずらすbit数。正規化数は11、非正規化数は11+1<=o<=11+53
      if (o < 64) {
        xb = xc << -o;
        xc = xd << -o | xc >>> o;
        xd >>>= o;
      } else {
        xb = xc;
        xc = xd;
        xd = 0L;
      }
      if ((xc | xb) != 0L) {  //端数が0ではない
        epbFpsr |= EPB_FPSR_X2;  //不正確な結果
        epbExceptionOperandExponent = x.flg & M | 0x3fff + 0x6000 + x.epp << 16;
        epbExceptionOperandMantissa = x.dvl;
        if (roundingMode == EPB_MODE_RN && xc < 0L && (xd << 63 | xc << 1 | xb) != 0L ||  //RNでguard bitが1かつLSBまたはguard bit以外の端数が0ではないまたは
            roundingMode == EPB_MODE_RM && xf < 0 ||  //端数が0ではなくてRMで-または
            roundingMode == EPB_MODE_RP && 0 <= xf) {  //端数が0ではなくてRPで+のとき
          xd++;  //繰り上げる
          if (xd >>> 53 != 0L) {  //繰り上がって溢れたとき
            xd = 1L << 52;
            xe++;  //指数部をインクリメントする。ここでxe=1024になる場合がある
            if (1023 < xe) {  //指数部が大きすぎる
              epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
              return this.sete (OVFL_RESULTS[EPB_PREC_DBL << 3 | roundingMode << 1 | xf >>> 31]);  //±Inf
            }
          } else if (11 < o) {  //非正規化数のとき
            if (xd << o - 1 < 0L) {  //1bit増えたとき
              xe++;  //指数部をインクリメントする
/* roundd */
              if (xe == -1022) {  //非正規化数が繰り上がって正規化数になったとき
                //xd = 1L << 52;
                epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
                epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
                epbExceptionOperandMantissa = xd;
              }
/**/
            }
          }
        }
        //RZ toward zeroのときは端数を切り捨てるだけなので何もしなくてよい
        if (xe <= -1023) {  //非正規化数
          epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
          if (xd == 0L) {  //非正規化数でxe==-1075だったとき、先頭の1がxcにあって丸めで繰り上がらなかった
            return this.sete (UNFL_RESULTS[EPB_PREC_DBL << 3 | roundingMode << 1 | xf >>> 31]);  //±0
          }
        }  //if 非正規化数
      } else {  //端数が0
        if (xe <= -1023) {  //非正規化数
          epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
          epbExceptionOperandExponent = x.flg & M | 0x3fff + 0x6000 + x.epp << 16;
          epbExceptionOperandMantissa = x.dvl;
          if (xd == 0L) {  //非正規化数でxe==-1075だったとき、先頭の1がxcにあって丸めで繰り上がらなかった
            return this.sete (UNFL_RESULTS[EPB_PREC_DBL << 3 | roundingMode << 1 | xf >>> 31]);  //±0
          }
        }  //if 非正規化数
      }  //if 端数が0ではない/端数が0
      xd <<= Long.numberOfLeadingZeros (xd);  //xcとxbはゴミが残っているので加えないこと
      //結果
      this.flg = xf;
      this.epp = xe;
      this.dvl = xd;
      this.cvl = 0L;
      return this;
    }  //efp.roundd(EFP,int)

    //------------------------------------------------------------------------
    //x = x.roundf ()
    //x = x.roundf (roundingMode)
    //y = y.roundf (x)
    //y = y.roundf (x, roundingMode)
    //  float丸め
    //
    //  この関数はepbRoundingModeとepbRoundingPrecを無視する
    //  float(指数部8bit,仮数部23+1bit,非正規化数を含む)で表現できる値に丸める
    //  floatで表現できないときは±Infに変換する
    //
    public final EFP roundf () {
      return this.roundf (this, EPB_MODE_RN);
    }  //efp.roundf()
    public final EFP roundf (int roundingMode) {
      return this.roundf (this, roundingMode);
    }  //efp.roundf(int)
    public final EFP roundf (EFP x) {
      return this.roundf (x, EPB_MODE_RN);
    }  //efp.roundf(EFP)
    public final EFP roundf (EFP x, int roundingMode) {
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        this.flg = xf;
        return this;
      }
      //±0,±Inf,NaN以外
      int xe = x.epp;  //正規化数は-126<=xe<=127、非正規化数は-149<=xe<=-127
      long xd = x.dvl;
      long xc = x.cvl;
      if (xe < -150) {  //指数部が小さすぎる。非正規化数の最小値は2^-149だが丸めで繰り上がる場合があるので一旦2^-150まで受け入れる
        epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
        epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
        epbExceptionOperandMantissa = xd;
        return this.sete (UNFL_RESULTS[EPB_PREC_SGL << 3 | roundingMode << 1 | xf >>> 31]);  //±0
      }
      if (127 < xe) {  //指数部が大きすぎる
        if (true) {
          epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
          if ((xd << 24 | xc) != 0L) {  //端数が0ではない
            epbFpsr |= EPB_FPSR_X2;  //不正確な結果
          }
        } else {
          epbFpsr |= EPB_FPSR_OF | EPB_FPSR_X2;  //オーバーフロー、不正確な結果
        }
        epbExceptionOperandExponent = xf | 0x3fff - 0x6000 + xe << 16;
        epbExceptionOperandMantissa = xd;
        return this.sete (OVFL_RESULTS[EPB_PREC_SGL << 3 | roundingMode << 1 | xf >>> 31]);  //±Inf
      }
      long xb = 0L;
      int o = xe <= -127 ? 40 + -126 - xe : 40;  //右にずらすbit数。正規化数は40、非正規化数は40+1<=o<=40+24
      if (o < 64) {
        xb = xc << -o;
        xc = xd << -o | xc >>> o;
        xd >>>= o;
      } else {
        xb = xc;
        xc = xd;
        xd = 0L;
      }
      if ((xc | xb) != 0L) {  //端数が0ではない
        epbFpsr |= EPB_FPSR_X2;  //不正確な結果
        epbExceptionOperandExponent = x.flg & M | 0x3fff + 0x6000 + x.epp << 16;
        epbExceptionOperandMantissa = x.dvl;
        if (roundingMode == EPB_MODE_RN && xc < 0L && (xd << -1 | xc << 1 | xb) != 0L ||  //RNでguard bitが1かつLSBまたはguard bit以外の端数が0ではないまたは
            roundingMode == EPB_MODE_RM && xf < 0 ||  //端数が0ではなくてRMで-または
            roundingMode == EPB_MODE_RP && 0 <= xf) {  //端数が0ではなくてRPで+のとき
          xd++;  //繰り上げる
          if (xd >>> 24 != 0L) {  //繰り上がって溢れたとき
            xd = 1L << 23;
            xe++;  //指数部をインクリメントする。ここでxe=128になる場合がある
            if (127 < xe) {  //指数部が大きすぎる
              epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
              return this.sete (OVFL_RESULTS[EPB_PREC_SGL << 3 | roundingMode << 1 | xf >>> 31]);  //±Inf
            }
          } else if (40 < o) {  //非正規化数のとき
            if (xd << o - 1 < 0L) {  //1bit増えたとき
              xe++;  //指数部をインクリメントする
/* roundf */
              if (xe == -126) {  //非正規化数が繰り上がって正規化数になったとき
                //xd = 1L << 23;
                epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
                epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
                epbExceptionOperandMantissa = xd;
              }
/**/
            }
          }
        }
        //RZ toward zeroのときは端数を切り捨てるだけなので何もしなくてよい
        if (xe <= -127) {  //非正規化数
          epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
          if (xd == 0L) {  //非正規化数でxe==-150だったとき、先頭の1がxcにあって丸めで繰り上がらなかった
            return this.sete (UNFL_RESULTS[EPB_PREC_SGL << 3 | roundingMode << 1 | xf >>> 31]);  //±0
          }
        }  //if 非正規化数
      } else {  //端数が0
        if (xe <= -127) {  //非正規化数
          epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
          epbExceptionOperandExponent = x.flg & M | 0x3fff + 0x6000 + x.epp << 16;
          epbExceptionOperandMantissa = x.dvl;
          if (xd == 0L) {  //非正規化数でxe==-150だったとき、先頭の1がxcにあって丸めで繰り上がらなかった
            return this.sete (UNFL_RESULTS[EPB_PREC_SGL << 3 | roundingMode << 1 | xf >>> 31]);  //±0
          }
        }
      }
      xd <<= Long.numberOfLeadingZeros (xd);  //xcとxbはゴミが残っているので加えないこと
      //結果
      this.flg = xf;
      this.epp = xe;
      this.dvl = xd;
      this.cvl = 0L;
      return this;
    }  //efp.roundf(EFP,int)

    //------------------------------------------------------------------------
    //x = x.roundg ()
    //x = x.roundg (roundingMode)
    //y = y.roundg (x)
    //y = y.roundg (x, roundingMode)
    //  xsg丸め
    //
    //  この関数はepbRoundingModeとepbRoundingPrecを無視する
    //  xsg(指数部15bit,仮数部23+1bit,非正規化数を含む)で表現できる値に丸める
    //  xsgで表現できないときは±Infに変換する
    //
    public final EFP roundg () {
      return this.roundg (this, EPB_MODE_RN);
    }  //efp.roundg()
    public final EFP roundg (int roundingMode) {
      return this.roundg (this, roundingMode);
    }  //efp.roundg(int)
    public final EFP roundg (EFP x) {
      return this.roundg (x, EPB_MODE_RN);
    }  //efp.roundg(EFP)
    public final EFP roundg (EFP x, int roundingMode) {
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        this.flg = xf;
        return this;
      }
      //±0,±Inf,NaN以外
      int xe = x.epp;  //正規化数は-16383<=xe<=16383、非正規化数は-16406<=xe<=-16384
      long xd = x.dvl;
      long xc = x.cvl;
      if (xe < -16407) {  //指数部が小さすぎる。非正規化数の最小値は2^-16406だが丸めで繰り上がる場合があるので一旦2^-16407まで受け入れる
        epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
        epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
        epbExceptionOperandMantissa = xd;
        return this.sete (UNFL_RESULTS[EPB_PREC_XSG << 3 | roundingMode << 1 | xf >>> 31]);  //±0
      }
      if (16383 < xe) {  //指数部が大きすぎる
        if (true) {
          epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
          if ((xd << 24 | xc) != 0L) {  //端数が0ではない
            epbFpsr |= EPB_FPSR_X2;  //不正確な結果
          }
        } else {
          epbFpsr |= EPB_FPSR_OF | EPB_FPSR_X2;  //オーバーフロー、不正確な結果
        }
        epbExceptionOperandExponent = xf | 0x3fff - 0x6000 + xe << 16;
        epbExceptionOperandMantissa = xd;
        return this.sete (OVFL_RESULTS[EPB_PREC_XSG << 3 | roundingMode << 1 | xf >>> 31]);  //±Inf
      }
      long xb = 0L;
      int o = xe <= -16384 ? 40 + -16383 - xe : 40;  //右にずらすbit数。正規化数は40、非正規化数は40+1<=o<=40+24
      if (o < 64) {
        xb = xc << -o;
        xc = xd << -o | xc >>> o;
        xd >>>= o;
      } else {
        xb = xc;
        xc = xd;
        xd = 0L;
      }
      if ((xc | xb) != 0L) {  //端数が0ではない
        epbFpsr |= EPB_FPSR_X2;  //不正確な結果
        epbExceptionOperandExponent = x.flg & M | 0x3fff + 0x6000 + x.epp << 16;
        epbExceptionOperandMantissa = x.dvl;
        if (roundingMode == EPB_MODE_RN && xc < 0L && (xd << -1 | xc << 1 | xb) != 0L ||  //RNでguard bitが1かつLSBまたはguard bit以外の端数が0ではないまたは
            roundingMode == EPB_MODE_RM && xf < 0 ||  //端数が0ではなくてRMで-または
            roundingMode == EPB_MODE_RP && 0 <= xf) {  //端数が0ではなくてRPで+のとき
          xd++;  //繰り上げる
          if (xd >>> 24 != 0L) {  //繰り上がって溢れたとき
            xd = 1L << 23;
            xe++;  //指数部をインクリメントする。ここでxe=16384になる場合がある
            if (16383 < xe) {  //指数部が大きすぎる
              epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
              return this.sete (OVFL_RESULTS[EPB_PREC_XSG << 3 | roundingMode << 1 | xf >>> 31]);  //±Inf
            }
          } else if (40 < o) {  //非正規化数のとき
            if (xd << o - 1 < 0L) {  //1bit増えたとき
              xe++;  //指数部をインクリメントする
/* roundg
              if (xe == -16383) {  //非正規化数が繰り上がって正規化数になったとき
                //xd = 1L << 23;
                epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
                epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
                epbExceptionOperandMantissa = xd;
              }
*/
            }
          }
        }
        //RZ toward zeroのときは端数を切り捨てるだけなので何もしなくてよい
        if (xe <= -16384) {  //非正規化数
          epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
          if (xd == 0L) {  //非正規化数でxe==-16407だったとき、先頭の1がxcにあって丸めで繰り上がらなかった
            return this.sete (UNFL_RESULTS[EPB_PREC_XSG << 3 | roundingMode << 1 | xf >>> 31]);  //±0
          }
        }  //if 非正規化数
      } else {  //端数が0
        if (xe <= -16384) {  //非正規化数
          epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
          epbExceptionOperandExponent = x.flg & M | 0x3fff + 0x6000 + x.epp << 16;
          epbExceptionOperandMantissa = x.dvl;
          if (xd == 0L) {  //非正規化数でxe==-16407だったとき、先頭の1がxcにあって丸めで繰り上がらなかった
            return this.sete (UNFL_RESULTS[EPB_PREC_XSG << 3 | roundingMode << 1 | xf >>> 31]);  //±0
          }
        }
      }
      xd <<= Long.numberOfLeadingZeros (xd);  //xcとxbはゴミが残っているので加えないこと
      //結果
      this.flg = xf;
      this.epp = xe;
      this.dvl = xd;
      this.cvl = 0L;
      return this;
    }  //efp.roundg(EFP,int)

    //------------------------------------------------------------------------
    //x = x.roundi ()
    //x = x.roundi (roundingMode)
    //x = x.roundi (x)
    //x = x.roundi (x, roundingMode)
    //  int丸め
    //
    //  int(32bit整数)に丸める
    //  2^31-1よりも大きい数は2^31-1に、-2^31よりも小さい数は-2^31に変換する(飽和変換)
    //  NaNは0に変換する
    //
    public final EFP roundi () {
      return this.roundi (this, EPB_MODE_RN);
    }  //efp.roundi()
    public final EFP roundi (int roundingMode) {
      return this.roundi (this, roundingMode);
    }  //efp.roundi(int)
    public final EFP roundi (EFP x) {
      return this.roundi (x, EPB_MODE_RN);
    }  //efp.roundi(EFP)
    public final EFP roundi (EFP x, int roundingMode) {
      return this.seti (x.geti (roundingMode));
    }  //efp.roundi(EFP,int)

    //------------------------------------------------------------------------
    //x = x.roundl ()
    //x = x.roundl (roundingMode)
    //x = x.roundl (x)
    //x = x.roundl (x, roundingMode)
    //  long丸め
    //
    //  long(64bit整数)に丸める
    //  2^63-1よりも大きい数は2^63-1に、-2^63よりも小さい数は-2^63に変換する(飽和変換)
    //  NaNは0に変換する
    //
    public final EFP roundl () {
      return this.roundl (this, EPB_MODE_RN);
    }  //efp.roundl()
    public final EFP roundl (int roundingMode) {
      return this.roundl (this, roundingMode);
    }  //efp.roundl(int)
    public final EFP roundl (EFP x) {
      return this.roundl (x, EPB_MODE_RN);
    }  //efp.roundl(EFP)
    public final EFP roundl (EFP x, int roundingMode) {
      return this.setl (x.getl (roundingMode));
    }  //efp.roundl(EFP,int)

    //------------------------------------------------------------------------
    //x = x.roundmand ()
    //x = x.roundmand (roundingMode)
    //x = x.roundmand (x)
    //x = x.roundmand (x, roundingMode)
    //  仮数部double丸め
    //  仮数部を(1+52)bitに丸める
    //
    public final EFP roundmand () {
      return this.roundmand (this, EPB_MODE_RN);
    }  //efp.roundmand()
    public final EFP roundmand (int roundingMode) {
      return this.roundmand (this, roundingMode);
    }  //efp.roundmand(int)
    public final EFP roundmand (EFP x) {
      return this.roundmand (x, EPB_MODE_RN);
    }  //efp.roundmand(EFP)
    public final EFP roundmand (EFP x, int roundingMode) {
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        this.flg = xf;
        return this;
      }
      //±0,±Inf,NaN以外
      int xe = x.epp;
      long xd = x.dvl;
      long xc = x.cvl;
      long xb = 0L;
      xb = xc << -11;
      xc = xd << -11 | xc >>> 11;
      xd >>>= 11;
      if ((xc | xb) != 0L) {  //端数が0ではない
        epbFpsr |= EPB_FPSR_X2;  //不正確な結果
        epbExceptionOperandExponent = x.flg & M | 0x3fff + 0x6000 + x.epp << 16;
        epbExceptionOperandMantissa = x.dvl;
        if (roundingMode == EPB_MODE_RN && xc < 0L && (xd << 63 | xc << 1 | xb) != 0L ||  //RNでguard bitが1かつLSBまたはguard bit以外の端数が0ではないまたは
            roundingMode == EPB_MODE_RM && xf < 0 ||  //端数が0ではなくてRMで-または
            roundingMode == EPB_MODE_RP && 0 <= xf) {  //端数が0ではなくてRPで+のとき
          xd++;  //繰り上げる
          if (xd >>> 53 != 0L) {  //繰り上がって溢れたとき
            xd = 1L << 52;
            xe++;  //指数部をインクリメントする
          }
        }
        //RZ toward zeroのときは端数を切り捨てるだけなので何もしなくてよい
      }  //if 端数が0ではない
      xd <<= 11;  //xcとxbはゴミが残っているので加えないこと
      //結果
      this.flg = xf;
      this.epp = xe;
      this.dvl = xd;
      this.cvl = 0L;
      return this;
    }  //efp.roundmand(EFP,int)

    //------------------------------------------------------------------------
    //x = x.roundmanf ()
    //x = x.roundmanf (roundingMode)
    //y = y.roundmanf (x)
    //y = y.roundmanf (x, roundingMode)
    //  仮数部float丸め
    //  仮数部を(1+23)bitに丸める
    //
    public final EFP roundmanf () {
      return this.roundmanf (this, EPB_MODE_RN);
    }  //efp.roundmanf()
    public final EFP roundmanf (int roundingMode) {
      return this.roundmanf (this, roundingMode);
    }  //efp.roundmanf(int)
    public final EFP roundmanf (EFP x) {
      return this.roundmanf (x, EPB_MODE_RN);
    }  //efp.roundmanf(EFP)
    public final EFP roundmanf (EFP x, int roundingMode) {
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        this.flg = xf;
        return this;
      }
      //±0,±Inf,NaN以外
      int xe = x.epp;
      long xd = x.dvl;
      long xc = x.cvl;
      long xb = 0L;
      xb = xc << -40;
      xc = xd << -40 | xc >>> 40;
      xd >>>= 40;
      if ((xc | xb) != 0L) {  //端数が0ではない
        epbFpsr |= EPB_FPSR_X2;  //不正確な結果
        epbExceptionOperandExponent = x.flg & M | 0x3fff + 0x6000 + x.epp << 16;
        epbExceptionOperandMantissa = x.dvl;
        if (roundingMode == EPB_MODE_RN && xc < 0L && (xd << 63 | xc << 1 | xb) != 0L ||  //RNでguard bitが1かつLSBまたはguard bit以外の端数が0ではないまたは
            roundingMode == EPB_MODE_RM && xf < 0 ||  //端数が0ではなくてRMで-または
            roundingMode == EPB_MODE_RP && 0 <= xf) {  //端数が0ではなくてRPで+のとき
          xd++;  //繰り上げる
          if (xd >>> 24 != 0L) {  //繰り上がって溢れたとき
            xd = 1L << 23;
            xe++;  //指数部をインクリメントする
          }
        }
        //RZ toward zeroのときは端数を切り捨てるだけなので何もしなくてよい
      }  //if 端数が0ではない
      xd <<= 40;  //xcとxbはゴミが残っているので加えないこと
      //結果
      this.flg = xf;
      this.epp = xe;
      this.dvl = xd;
      this.cvl = 0L;
      return this;
    }  //efp.roundmanf(EFP,int)

    //------------------------------------------------------------------------
    //x = x.roundmanx ()
    //x = x.roundmanx (roundingMode)
    //x = x.roundmanx (x)
    //x = x.roundmanx (x, roundingMode)
    //  仮数部extended丸め
    //  仮数部を(1+63)bitに丸める
    //
    public final EFP roundmanx () {
      return this.roundmanx (this, EPB_MODE_RN);
    }  //efp.roundmanx()
    public final EFP roundmanx (int roundingMode) {
      return this.roundmanx (this, roundingMode);
    }  //efp.roundmanx(int)
    public final EFP roundmanx (EFP x) {
      return this.roundmanx (x, EPB_MODE_RN);
    }  //efp.roundmanx(EFP)
    public final EFP roundmanx (EFP x, int roundingMode) {
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        this.flg = xf;
        return this;
      }
      //±0,±Inf,NaN以外
      int xe = x.epp;
      long xd = x.dvl;
      long xc = x.cvl;
      long xb = 0L;
      if ((xc | xb) != 0L) {  //端数が0ではない
        epbFpsr |= EPB_FPSR_X2;  //不正確な結果
        epbExceptionOperandExponent = x.flg & M | 0x3fff + 0x6000 + x.epp << 16;
        epbExceptionOperandMantissa = x.dvl;
        if (roundingMode == EPB_MODE_RN && xc < 0L && (xd << 63 | xc << 1 | xb) != 0L ||  //RNでguard bitが1かつLSBまたはguard bit以外の端数が0ではないまたは
            roundingMode == EPB_MODE_RM && xf < 0 ||  //端数が0ではなくてRMで-または
            roundingMode == EPB_MODE_RP && 0 <= xf) {  //端数が0ではなくてRPで+のとき
          xd++;  //繰り上げる
          if (xd == 0L) {  //繰り上がって溢れたとき
            xd = MSB;
            xe++;  //指数部をインクリメントする
          }
        }
        //RZ toward zeroのときは端数を切り捨てるだけなので何もしなくてよい
      }  //if 端数が0ではない
      xd <<= Long.numberOfLeadingZeros (xd);  //xcとxbはゴミが残っているので加えないこと
      //結果
      this.flg = xf;
      this.epp = xe;
      this.dvl = xd;
      this.cvl = 0L;
      return this;
    }  //efp.roundmanx(EFP,int)

    //------------------------------------------------------------------------
    //x = x.roundmany ()
    //x = x.roundmany (roundingMode)
    //x = x.roundmany (x)
    //x = x.roundmany (x, roundingMode)
    //  仮数部triple丸め
    //  仮数部を(1+79)bitに丸める
    //
    public final EFP roundmany () {
      return this.roundmany (this, EPB_MODE_RN);
    }  //efp.roundmany()
    public final EFP roundmany (int roundingMode) {
      return this.roundmany (this, roundingMode);
    }  //efp.roundmany(int)
    public final EFP roundmany (EFP x) {
      return this.roundmany (x, EPB_MODE_RN);
    }  //efp.roundmany(EFP)
    public final EFP roundmany (EFP x, int roundingMode) {
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        this.flg = xf;
        return this;
      }
      //±0,±Inf,NaN以外
      int xe = x.epp;
      long xd = x.dvl;
      long xc = x.cvl;
      long xb = 0L;
      xb = xc << -48;
      xc = xd << -48 | xc >>> 48;
      xd >>>= 48;
      if (xb != 0L) {  //端数が0ではない
        epbFpsr |= EPB_FPSR_X2;  //不正確な結果
        epbExceptionOperandExponent = x.flg & M | 0x3fff + 0x6000 + x.epp << 16;
        epbExceptionOperandMantissa = x.dvl;
        if (roundingMode == EPB_MODE_RN && xb < 0L && (xc << 63 | xb << 1) != 0L ||  //RNでguard bitが1かつLSBまたはguard bit以外の端数が0ではないまたは
            roundingMode == EPB_MODE_RM && xf < 0 ||  //端数が0ではなくてRMで-または
            roundingMode == EPB_MODE_RP && 0 <= xf) {  //端数が0ではなくてRPで+のとき
          xc++;  //繰り上げる
          if (xc == 0L) {  //繰り上がって溢れたとき
            xd++;  //繰り上げる
            if (xd >>> 16 != 0L) {  //繰り上がって溢れたとき
              xd = 1L << 15;
              xe++;  //指数部をインクリメントする
            }
          }
        }
        //RZ toward zeroのときは端数を切り捨てるだけなので何もしなくてよい
      }  //if 端数が0ではない
      xd = xd << 48 | xc >>> -48;
      xc <<= 48;  //xbはゴミが残っているので加えないこと
      //結果
      this.flg = xf;
      this.epp = xe;
      this.dvl = xd;
      this.cvl = xc;
      return this;
    }  //efp.roundmany(EFP,int)

    //------------------------------------------------------------------------
    //x = x.roundx ()
    //x = x.roundx (roundingMode)
    //x = x.roundx (x)
    //x = x.roundx (x, roundingMode)
    //  extended丸め
    //
    //  この関数はepbRoundingModeとepbRoundingPrecを無視する
    //  extended(指数部15bit,仮数部64bit,非正規化数を含む)で表現できる値に丸める
    //  extendedで表現できないときは±Infに変換する
    //
    public final EFP roundx () {
      return this.roundx (this, EPB_MODE_RN);
    }  //efp.roundx()
    public final EFP roundx (int roundingMode) {
      return this.roundx (this, roundingMode);
    }  //efp.roundx(int)
    public final EFP roundx2 (int roundingMode) {
      return this.roundx2 (this, roundingMode);
    }  //efp.roundx(int)
    public final EFP roundx (EFP x) {
      return this.roundx (x, EPB_MODE_RN);
    }  //efp.roundx(EFP)
    public final EFP roundx (EFP x, int roundingMode) {
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        this.flg = xf;
        return this;
      }
      //±0,±Inf,NaN以外
      int xe = x.epp;  //正規化数は-16383<=xe<=16383、非正規化数は-16446<=xe<=-16384
      long xd = x.dvl;
      long xc = x.cvl;
      if (xe < -16447) {  //指数部が小さすぎる。非正規化数の最小値は2^-16446だが丸めで繰り上がる場合があるので一旦2^-16447まで受け入れる
        epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
        epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
        epbExceptionOperandMantissa = xd;
        return this.sete (UNFL_RESULTS[EPB_PREC_EXD << 3 | roundingMode << 1 | xf >>> 31]);  //±0
      }
      if (16383 < xe) {  //指数部が大きすぎる
        if (true) {
          epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
          if (xc != 0L) {  //端数が0ではない
            epbFpsr |= EPB_FPSR_X2;  //不正確な結果
          }
        } else {
          epbFpsr |= EPB_FPSR_OF | EPB_FPSR_X2;  //オーバーフロー、不正確な結果
        }
        epbExceptionOperandExponent = xf | 0x3fff - 0x6000 + xe << 16;
        epbExceptionOperandMantissa = xd;
        return this.sete (OVFL_RESULTS[EPB_PREC_EXD << 3 | roundingMode << 1 | xf >>> 31]);  //±Inf
      }
      long xb = 0L;
      int o = xe <= -16384 ? 0 + -16383 - xe : 0;  //右にずらすbit数。正規化数は0、非正規化数は0+1<=o<=0+64
      if (o == 0) {
      } else if (o < 64) {
        xb = xc << -o;
        xc = xd << -o | xc >>> o;
        xd >>>= o;
      } else {
        xb = xc;
        xc = xd;
        xd = 0L;
      }
      if ((xc | xb) != 0L) {  //端数が0ではない
        epbFpsr |= EPB_FPSR_X2;  //不正確な結果
        epbExceptionOperandExponent = x.flg & M | 0x3fff + 0x6000 + x.epp << 16;
        epbExceptionOperandMantissa = x.dvl;
        if (roundingMode == EPB_MODE_RN && xc < 0L && (xd << 63 | xc << 1 | xb) != 0L ||  //RNでguard bitが1かつLSBまたはguard bit以外の端数が0ではないまたは
            roundingMode == EPB_MODE_RM && xf < 0 ||  //端数が0ではなくてRMで-または
            roundingMode == EPB_MODE_RP && 0 <= xf) {  //端数が0ではなくてRPで+のとき
          xd++;  //繰り上げる
          if (xd == 0L) {  //繰り上がって溢れたとき
            xd = MSB;
            xe++;  //指数部をインクリメントする。ここでxe=16384になる場合がある
            if (16383 < xe) {  //指数部が大きすぎる
              epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
              return this.sete (OVFL_RESULTS[EPB_PREC_EXD << 3 | roundingMode << 1 | xf >>> 31]);  //±Inf
            }
          } else if (0 < o) {  //非正規化数のとき
            if (xd << o - 1 < 0L) {  //1bit増えたとき
              xe++;  //指数部をインクリメントする
/* roundx
              if (xe == -16383) {  //非正規化数が繰り上がって正規化数になったとき
                //xd = MSB;
                epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
                epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
                epbExceptionOperandMantissa = xd;
              }
*/
            }
          }
        }
        //RZ toward zeroのときは端数を切り捨てるだけなので何もしなくてよい
        if (xe <= -16384) {  //非正規化数
          epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
          if (xd == 0L) {  //非正規化数でxe==-16447だったとき、先頭の1がxcにあって丸めで繰り上がらなかった
            return this.sete (UNFL_RESULTS[EPB_PREC_EXD << 3 | roundingMode << 1 | xf >>> 31]);  //±0
          }
        }  //if 非正規化数
      } else {  //端数が0
        if (xe <= -16384) {  //非正規化数
          epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
          epbExceptionOperandExponent = x.flg & M | 0x3fff + 0x6000 + x.epp << 16;
          epbExceptionOperandMantissa = x.dvl;
          if (xd == 0L) {  //非正規化数でxe==-16447だったとき、先頭の1がxcにあって丸めで繰り上がらなかった
            return this.sete (UNFL_RESULTS[EPB_PREC_EXD << 3 | roundingMode << 1 | xf >>> 31]);  //±0
          }
        }  //if 非正規化数
      }  //if 端数が0ではない/端数が0
      xd <<= Long.numberOfLeadingZeros (xd);  //xcとxbはゴミが残っているので加えないこと
      //結果
      this.flg = xf;
      this.epp = xe;
      this.dvl = xd;
      this.cvl = 0L;
      return this;
    }  //efp.roundx(EFP,int)
    public final EFP roundx2 (EFP x, int roundingMode) {
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        this.flg = xf;
        return this;
      }
      //±0,±Inf,NaN以外
      int xe = x.epp;  //正規化数は-16383<=xe<=16383、非正規化数は-16446<=xe<=-16384
      long xd = x.dvl;
      long xc = x.cvl;
      if (xe < -16447) {  //指数部が小さすぎる。非正規化数の最小値は2^-16446だが丸めで繰り上がる場合があるので一旦2^-16447まで受け入れる
        epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
        epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
        epbExceptionOperandMantissa = xd;
        return this.sete (UNFL_RESULTS[EPB_PREC_EXD << 3 | roundingMode << 1 | xf >>> 31]);  //±0
      }
      if (16383 < xe) {  //指数部が大きすぎる
        if (true) {
          epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
          if (xc != 0L) {  //端数が0ではない
            epbFpsr |= EPB_FPSR_X2;  //不正確な結果
          }
        } else {
          epbFpsr |= EPB_FPSR_OF | EPB_FPSR_X2;  //オーバーフロー、不正確な結果
        }
        epbExceptionOperandExponent = xf | 0x3fff - 0x6000 + xe << 16;
        epbExceptionOperandMantissa = xd;
        return this.sete (OVFL_RESULTS[EPB_PREC_EXD << 3 | roundingMode << 1 | xf >>> 31]);  //±Inf
      }
      long xb = 0L;
      int o = xe <= -16384 ? 0 + -16383 - xe : 0;  //右にずらすbit数。正規化数は0、非正規化数は0+1<=o<=0+64
      if (o == 0) {
      } else if (o < 64) {
        xb = xc << -o;
        xc = xd << -o | xc >>> o;
        xd >>>= o;
      } else {
        xb = xc;
        xc = xd;
        xd = 0L;
      }
      if ((xc | xb) != 0L) {  //端数が0ではない
        epbFpsr |= EPB_FPSR_X2;  //不正確な結果
        epbExceptionOperandExponent = x.flg & M | 0x3fff + 0x6000 + x.epp << 16;
        epbExceptionOperandMantissa = x.dvl;
        if (roundingMode == EPB_MODE_RN && xc < 0L && (xd << 63 | xc << 1 | xb) != 0L ||  //RNでguard bitが1かつLSBまたはguard bit以外の端数が0ではないまたは
            roundingMode == EPB_MODE_RM && xf < 0 ||  //端数が0ではなくてRMで-または
            roundingMode == EPB_MODE_RP && 0 <= xf) {  //端数が0ではなくてRPで+のとき
          xd++;  //繰り上げる
          if (xd == 0L) {  //繰り上がって溢れたとき
            xd = MSB;
            xe++;  //指数部をインクリメントする。ここでxe=16384になる場合がある
            if (16383 < xe) {  //指数部が大きすぎる
              epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
              return this.sete (OVFL_RESULTS[EPB_PREC_EXD << 3 | roundingMode << 1 | xf >>> 31]);  //±Inf
            }
          } else if (0 < o) {  //非正規化数のとき
            if (xd << o - 1 < 0L) {  //1bit増えたとき
              xe++;  //指数部をインクリメントする
/* roundx2 */
              if (xe == -16383) {  //非正規化数が繰り上がって正規化数になったとき
                //xd = MSB;
                epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
                epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
                epbExceptionOperandMantissa = xd;
              }
/**/
            }
          }
        }
        //RZ toward zeroのときは端数を切り捨てるだけなので何もしなくてよい
        if (xe <= -16384) {  //非正規化数
          epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
          if (xd == 0L) {  //非正規化数でxe==-16447だったとき、先頭の1がxcにあって丸めで繰り上がらなかった
            return this.sete (UNFL_RESULTS[EPB_PREC_EXD << 3 | roundingMode << 1 | xf >>> 31]);  //±0
          }
        }  //if 非正規化数
      } else {  //端数が0
        if (xe <= -16384) {  //非正規化数
          epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
          epbExceptionOperandExponent = x.flg & M | 0x3fff + 0x6000 + x.epp << 16;
          epbExceptionOperandMantissa = x.dvl;
          if (xd == 0L) {  //非正規化数でxe==-16447だったとき、先頭の1がxcにあって丸めで繰り上がらなかった
            return this.sete (UNFL_RESULTS[EPB_PREC_EXD << 3 | roundingMode << 1 | xf >>> 31]);  //±0
          }
        }  //if 非正規化数
      }  //if 端数が0ではない/端数が0
      xd <<= Long.numberOfLeadingZeros (xd);  //xcとxbはゴミが残っているので加えないこと
      //結果
      this.flg = xf;
      this.epp = xe;
      this.dvl = xd;
      this.cvl = 0L;
      return this;
    }  //efp.roundx(EFP,int)

    //------------------------------------------------------------------------
    //x = x.roundy ()
    //x = x.roundy (roundingMode)
    //x = x.roundy (x)
    //x = x.roundy (x, roundingMode)
    //  triple丸め
    //
    //  この関数はepbRoundingModeとepbRoundingPrecを無視する
    //  triple(指数部15bit,仮数部80bit,非正規化数を含む)で表現できる値に丸める
    //  tripleで表現できないときは±Infに変換する
    //
    public final EFP roundy () {
      return this.roundy (this, EPB_MODE_RN);
    }  //efp.roundy()
    public final EFP roundy (int roundingMode) {
      return this.roundy (this, roundingMode);
    }  //efp.roundy(int)
    public final EFP roundy2 (int roundingMode) {
      return this.roundy2 (this, roundingMode);
    }  //efp.roundy(int)
    public final EFP roundy (EFP x) {
      return this.roundy (x, EPB_MODE_RN);
    }  //efp.roundy(EFP)
    public final EFP roundy (EFP x, int roundingMode) {
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        this.flg = xf;
        return this;
      }
      //±0,±Inf,NaN以外
      int xe = x.epp;  //正規化数は-16383<=xe<=16383、非正規化数は-16462<=xe<=-16384
      long xd = x.dvl;
      long xc = x.cvl;
      if (xe < -16463) {  //指数部が小さすぎる。非正規化数の最小値は2^-16462だが丸めで繰り上がる場合があるので一旦2^-16463まで受け入れる
        epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
        epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
        epbExceptionOperandMantissa = xd;
        return this.sete (UNFL_RESULTS[EPB_PREC_TPL << 3 | roundingMode << 1 | xf >>> 31]);  //±0
      }
      if (16383 < xe) {  //指数部が大きすぎる
        if (true) {
          epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
          if (xc << 16 != 0L) {  //端数が0ではない
            epbFpsr |= EPB_FPSR_X2;  //不正確な結果
          }
        } else {
          epbFpsr |= EPB_FPSR_OF | EPB_FPSR_X2;  //オーバーフロー、不正確な結果
        }
        epbExceptionOperandExponent = xf | 0x3fff - 0x6000 + xe << 16;
        epbExceptionOperandMantissa = xd;
        return this.sete (OVFL_RESULTS[EPB_PREC_TPL << 3 | roundingMode << 1 | xf >>> 31]);  //±Inf
      }
      long xb = 0L;
      long xa = 0L;
      int o = xe <= -16384 ? 48 + -16383 - xe : 48;  //右にずらすbit数。正規化数は48、非正規化数は48+1<=o<=48+80
      if (o < 64) {
        xb = xc << -o;
        xc = xd << -o | xc >>> o;
        xd >>>= o;
      } else if (o == 64) {
        xb = xc;
        xc = xd;
        xd = 0L;
      } else if (o < 128) {
        xa = xc << -o;
        xb = xd << -o | xc >>> o;
        xc = xd >>> o;
        xd = 0L;
      } else {
        xa = xc;
        xb = xd;
        xc = 0L;
        xd = 0L;
      }
      if ((xb | xa) != 0L) {  //端数が0ではない
        epbFpsr |= EPB_FPSR_X2;  //不正確な結果
        epbExceptionOperandExponent = x.flg & M | 0x3fff + 0x6000 + x.epp << 16;
        epbExceptionOperandMantissa = x.dvl;
        if (roundingMode == EPB_MODE_RN && xb < 0L && (xc << 63 | xb << 1 | xa) != 0L ||  //RNでguard bitが1かつLSBまたはguard bit以外の端数が0ではないまたは
            roundingMode == EPB_MODE_RM && xf < 0 ||  //端数が0ではなくてRMで-または
            roundingMode == EPB_MODE_RP && 0 <= xf) {  //端数が0ではなくてRPで+のとき
          xc++;  //繰り上げる
          if (xc == 0L) {  //繰り上がって溢れたとき
            xd++;  //繰り上げる
            if (xd >>> 16 != 0L) {  //繰り上がって溢れたとき
              //xd = 1L << 15;
              xe++;  //指数部をインクリメントする。ここでxe=16384になる場合がある
              if (16383 < xe) {  //指数部が大きすぎる
                epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
                return this.sete (OVFL_RESULTS[EPB_PREC_TPL << 3 | roundingMode << 1 | xf >>> 31]);  //±Inf
              }  //if 指数部が大きすぎる
            } else if (48 < o) {  //非正規化数のとき
              if (xd << o - 1 < 0L) {  //1bit増えたとき
                xe++;  //指数部をインクリメントする
/* roundy
                if (xe == -16383) {  //非正規化数が繰り上がって正規化数になったとき
                  //xd = 1L << 15;
                  epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
                  epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
                  epbExceptionOperandMantissa = xd;
                }
*/
              }
            }
          }
        }
        //RZ toward zeroのときは端数を切り捨てるだけなので何もしなくてよい
        if (xe <= -16384) {  //非正規化数
          epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
          if ((xd | xc) == 0L) {  //非正規化数でxe==-16463だったとき、先頭の1がxbにあって丸めで繰り上がらなかった
            return this.sete (UNFL_RESULTS[EPB_PREC_TPL << 3 | roundingMode << 1 | xf >>> 31]);  //±0
          }
        }  //if 非正規化数
      } else {  //端数が0
        if (xe <= -16384) {  //非正規化数
          epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
          epbExceptionOperandExponent = x.flg & M | 0x3fff + 0x6000 + x.epp << 16;
          epbExceptionOperandMantissa = x.dvl;
          if ((xd | xc) == 0L) {  //非正規化数でxe==-16463だったとき、先頭の1がxbにあって丸めで繰り上がらなかった
            return this.sete (UNFL_RESULTS[EPB_PREC_TPL << 3 | roundingMode << 1 | xf >>> 31]);  //±0
          }
        }  //if 非正規化数
      }  //if 端数が0ではない/端数が0
      if (xd != 0L) {
        o = Long.numberOfLeadingZeros (xd);
        xd = xd << o | xc >>> -o;
        xc <<= o;  //xbとxaはゴミが残っているので加えないこと
      } else {
        xd = xc << Long.numberOfLeadingZeros (xc);  //xbとxaはゴミが残っているので加えないこと
        xc = 0L;
      }
      //結果
      this.flg = xf;
      this.epp = xe;
      this.dvl = xd;
      this.cvl = xc;
      return this;
    }  //efp.roundy(EFP,int)
    public final EFP roundy2 (EFP x, int roundingMode) {
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        this.flg = xf;
        return this;
      }
      //±0,±Inf,NaN以外
      int xe = x.epp;  //正規化数は-16383<=xe<=16383、非正規化数は-16462<=xe<=-16384
      long xd = x.dvl;
      long xc = x.cvl;
      if (xe < -16463) {  //指数部が小さすぎる。非正規化数の最小値は2^-16462だが丸めで繰り上がる場合があるので一旦2^-16463まで受け入れる
        epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
        epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
        epbExceptionOperandMantissa = xd;
        return this.sete (UNFL_RESULTS[EPB_PREC_TPL << 3 | roundingMode << 1 | xf >>> 31]);  //±0
      }
      if (16383 < xe) {  //指数部が大きすぎる
        if (true) {
          epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
          if (xc << 16 != 0L) {  //端数が0ではない
            epbFpsr |= EPB_FPSR_X2;  //不正確な結果
          }
        } else {
          epbFpsr |= EPB_FPSR_OF | EPB_FPSR_X2;  //オーバーフロー、不正確な結果
        }
        epbExceptionOperandExponent = xf | 0x3fff - 0x6000 + xe << 16;
        epbExceptionOperandMantissa = xd;
        return this.sete (OVFL_RESULTS[EPB_PREC_TPL << 3 | roundingMode << 1 | xf >>> 31]);  //±Inf
      }
      long xb = 0L;
      long xa = 0L;
      int o = xe <= -16384 ? 48 + -16383 - xe : 48;  //右にずらすbit数。正規化数は48、非正規化数は48+1<=o<=48+80
      if (o < 64) {
        xb = xc << -o;
        xc = xd << -o | xc >>> o;
        xd >>>= o;
      } else if (o == 64) {
        xb = xc;
        xc = xd;
        xd = 0L;
      } else if (o < 128) {
        xa = xc << -o;
        xb = xd << -o | xc >>> o;
        xc = xd >>> o;
        xd = 0L;
      } else {
        xa = xc;
        xb = xd;
        xc = 0L;
        xd = 0L;
      }
      if ((xb | xa) != 0L) {  //端数が0ではない
        epbFpsr |= EPB_FPSR_X2;  //不正確な結果
        epbExceptionOperandExponent = x.flg & M | 0x3fff + 0x6000 + x.epp << 16;
        epbExceptionOperandMantissa = x.dvl;
        if (roundingMode == EPB_MODE_RN && xb < 0L && (xc << 63 | xb << 1 | xa) != 0L ||  //RNでguard bitが1かつLSBまたはguard bit以外の端数が0ではないまたは
            roundingMode == EPB_MODE_RM && xf < 0 ||  //端数が0ではなくてRMで-または
            roundingMode == EPB_MODE_RP && 0 <= xf) {  //端数が0ではなくてRPで+のとき
          xc++;  //繰り上げる
          if (xc == 0L) {  //繰り上がって溢れたとき
            xd++;  //繰り上げる
            if (xd >>> 16 != 0L) {  //繰り上がって溢れたとき
              //xd = 1L << 15;
              xe++;  //指数部をインクリメントする。ここでxe=16384になる場合がある
              if (16383 < xe) {  //指数部が大きすぎる
                epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
                return this.sete (OVFL_RESULTS[EPB_PREC_TPL << 3 | roundingMode << 1 | xf >>> 31]);  //±Inf
              }  //if 指数部が大きすぎる
            } else if (48 < o) {  //非正規化数のとき
              if (xd << o - 1 < 0L) {  //1bit増えたとき
                xe++;  //指数部をインクリメントする
/* roundy2 */
                if (xe == -16383) {  //非正規化数が繰り上がって正規化数になったとき
                  //xd = 1L << 15;
                  epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
                  epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + xe << 16;
                  epbExceptionOperandMantissa = xd;
                }
/**/
              }
            }
          }
        }
        //RZ toward zeroのときは端数を切り捨てるだけなので何もしなくてよい
        if (xe <= -16384) {  //非正規化数
          epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
          if ((xd | xc) == 0L) {  //非正規化数でxe==-16463だったとき、先頭の1がxbにあって丸めで繰り上がらなかった
            return this.sete (UNFL_RESULTS[EPB_PREC_TPL << 3 | roundingMode << 1 | xf >>> 31]);  //±0
          }
        }  //if 非正規化数
      } else {  //端数が0
        if (xe <= -16384) {  //非正規化数
          epbFpsr |= EPB_FPSR_UF;  //アンダーフロー
          epbExceptionOperandExponent = x.flg & M | 0x3fff + 0x6000 + x.epp << 16;
          epbExceptionOperandMantissa = x.dvl;
          if ((xd | xc) == 0L) {  //非正規化数でxe==-16463だったとき、先頭の1がxbにあって丸めで繰り上がらなかった
            return this.sete (UNFL_RESULTS[EPB_PREC_TPL << 3 | roundingMode << 1 | xf >>> 31]);  //±0
          }
        }  //if 非正規化数
      }  //if 端数が0ではない/端数が0
      if (xd != 0L) {
        o = Long.numberOfLeadingZeros (xd);
        xd = xd << o | xc >>> -o;
        xc <<= o;  //xbとxaはゴミが残っているので加えないこと
      } else {
        xd = xc << Long.numberOfLeadingZeros (xc);  //xbとxaはゴミが残っているので加えないこと
        xc = 0L;
      }
      //結果
      this.flg = xf;
      this.epp = xe;
      this.dvl = xd;
      this.cvl = xc;
      return this;
    }  //efp.roundy(EFP,int)

    //------------------------------------------------------------------------
    //x = x.scale (y)
    //  x*=2^trunc(y)
    //z = z.scale (x, y)
    //  z=x*2^trunc(y)
    //  2^trunc(y)倍
    //
    public final EFP scale (EFP y) {
      return this.scale (this, y);
    }  //efp.scale(EFP)
    public final EFP scale (EFP x, EFP y) {
      int xf = x.flg;
      int yf = y.flg;
      if ((xf | yf) << 1 != 0) {  //どちらかが±0,±Inf,NaN
        if ((xf | yf) << 3 < 0) {  //どちらかがNaN
          this.flg = N;
        } else if (yf << 1 < 0) {  //scale(±0,±0)=±0, scale(±Inf,±0)=±Inf, scale(±x,±0)=±x
          this.finish (x.flg, x.epp, x.dvl, x.cvl, 0L);
        } else if (yf << 2 < 0) {  //scale(±0,±Inf)=NaN,OE, scale(±Inf,±Inf)=NaN,OE, scale(±x,±Inf)=NaN,OE
          epbFpsr |= EPB_FPSR_OE;
          epbExceptionOperandExponent = yf & M | 0x7fff << 16;
          epbExceptionOperandMantissa = 0x0000000000000000L;
          this.flg = N;
        } else if (xf << 1 < 0) {  //scale(±0,±y)=±0
          this.flg = xf;
        } else if (xf << 2 < 0) {  //scale(±Inf,±y)=±Inf
          this.flg = xf;
        }
        return this;
      }
      //両方±0,±Inf,NaN以外
      //  スケールをround-to-zeroで整数にする
      //  geti()は飽和変換だが飽和させるとオペランドエラーがセットされてしまうので先に範囲を確認する
      int i = (16 <= y.epp ? yf < 0 ? -1 << 16 : 1 << 16 :   //スケールの絶対値が2^16以上
               y.geti ());
      if (i <= -1 << 14) {  //スケールが-2^14以下のとき常にアンダーフロー。MC68882に合わせる
        epbFpsr |= EPB_FPSR_UF | EPB_FPSR_X2;  //アンダーフロー、不正確な結果
        if (i <= -1 << 16) {  //スケールが-2^16以下
          epbExceptionOperandExponent = xf;
          epbExceptionOperandMantissa = x.dvl;
        } else {
          epbExceptionOperandExponent = xf | 0x3fff + 0x6000 + i << 16;
          epbExceptionOperandMantissa = x.dvl;
        }
        return this.sete (UNFL_RESULTS[epbRoundingPrec << 3 | epbRoundingMode << 1 | xf >>> 31]).finish ();  //±0
      }
      if (1 << 14 <= i) {  //スケールが2^14以上のとき常にオーバーフロー。MC68882に合わせる
        epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
        if (1 << 16 <= i) {  //スケールが2^16以上
          epbExceptionOperandExponent = xf;
          epbExceptionOperandMantissa = x.dvl;
        } else {
          epbExceptionOperandExponent = xf | 0x3fff - 0x6000 + i << 16;
          epbExceptionOperandMantissa = x.dvl;
        }
        return this.sete (OVFL_RESULTS[epbRoundingPrec << 3 | epbRoundingMode << 1 | xf >>> 31]).finish ();  //±Inf
      }
      return this.finish2 (xf, x.epp + i, x.dvl, x.cvl, 0L);  //スケールを加える
    }  //efp.scale(EFP,EFP)

    //------------------------------------------------------------------------
    //x = x.sec ()
    //  x=sec(x)
    //y = y.sec (x)
    //  y=sec(x)
    //  正割 secant セカント
    //
    //  グラフ
    //    perl -e "use Math::Trig;use Graph;$g=new Graph();$g->grid();$g->func(sub{sec($_[0])});print$g"
    //    echo read("../misc/efp.gp");eval("sec(x)=1/cos(x)");graph(sec) | gp -q
    //    +---------+---------+------*--+---------+---------+--*------+---------+---------+
    //    |                          *            |            *                          |
    //    |                          *            |            *                          |
    //    |                          *            |            *                          |
    //    |                          **           |           **                          |
    //    +                           *           +           *                           +
    //    |                           *           |           *                           |
    //    |                           *           |           *                           |
    //    |                           **          |          **                           |
    //    |                            *          |          *                            |
    //    +                            **         +         **                            +
    //    |                             **        |        **                             |
    //    |                              **       |       **                              |
    //    |                               **      |      **                               |
    //    |                                ****   |   ****                                |
    //    +                                   *********                                   +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +   **********                          +                          **********   +
    //    | ***        ****                       |                       ****        *** |
    //    ***             **                      |                      **             ***
    //    *                **                     |                     **                *
    //    |                 **                    |                    **                 |
    //    +                  *                    +                    *                  +
    //    |                  **                   |                   **                  |
    //    |                   *                   |                   *                   |
    //    |                   *                   |                   *                   |
    //    |                   **                  |                  **                   |
    //    +                    *                  +                  *                    +
    //    |                    *                  |                  *                    |
    //    |                    *                  |                  *                    |
    //    |                    **                 |                 **                    |
    //    |                     *                 |                 *                     |
    //    +---------+---------+-*-------+---------+---------+-------*-+---------+---------+
    //
    //  三角関数との関係
    //    sec(x)=1/cos(x)
    //
    public final EFP sec () {
      return this.sec (this);
    }  //efp.sec()
    public final EFP sec (EFP x) {
      return this.inner ().cos (x).outer ().rcp ();  //1/cos(x)
    }  //efp.sec(EFP)

    //------------------------------------------------------------------------
    //x = x.sech ()
    //  x=sech(x)
    //y = y.sech (x)
    //  y=sech(x)
    //  双曲線正割 hyperbolic secant ハイパボリックセカント
    //
    //  グラフ
    //    perl -e "use Math::Trig;use Graph;$g=new Graph();$g->grid();$g->func(sub{sech($_[0])});print$g"
    //    echo read("../misc/efp.gp");eval("sech(x)=1/cosh(x)");graph(sech) | gp -q
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                  ***********                                  +
    //    |                              *****    |    *****                              |
    //    |                          *****        |        *****                          |
    //    |                    *******            |            *******                    |
    //    |         ************                  |                  ************         |
    //    ***********---------+---------+---------+---------+---------+---------***********
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //
    //  双曲線関数との関係
    //    sech(x)=1/cosh(x)
    //
    //  指数関数との関係
    //    sech(x)=2/(e^x+e^-x)
    //           =2*e^x/((e^x)^2+1)
    //
    public final EFP sech () {
      return this.sech (this);
    }  //efp.sech()
    public final EFP sech (EFP x) {
      return this.inner ().cosh (x).outer ().rcp ();  //1/cosh(x)
    }  //efp.sech(EFP)

    //------------------------------------------------------------------------
    //y = y.set0 ()
    //  +0代入
    //
    public final EFP set0 () {
      this.flg = P | Z;
      //this.epp = 0;
      //this.dvl = 0L;
      //this.cvl = 0L;
      return this;
    }  //efp.set0()

    //------------------------------------------------------------------------
    //y = y.set1 ()
    //  +1代入
    //
    public final EFP set1 () {
      this.flg = P;
      this.epp = 0;
      this.dvl = MSB;
      this.cvl = 0L;
      return this;
    }  //efp.set1()

    //------------------------------------------------------------------------
    //y = y.setapery ()
    //  y=ζ(3)
    //  アペリーの定数 Apéry's constant
    //
    //  式
    //    ζ(3)=sum[n=1..∞]{1/n^3}
    //
    //  値
    //    echo read("../misc/efp.gp");printf("%.100g\n",zeta(3)) | gp -q
    //    1.202056903159594285399738161511449990764986292340498881792271555341838205786313090186455873609335258
    //
    //  参考
    //    https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%9A%E3%83%AA%E3%83%BC%E3%81%AE%E5%AE%9A%E6%95%B0
    //    https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%9A%E3%83%AA%E3%83%BC%E3%81%AE%E5%AE%9A%E7%90%86
    //    https://en.wikipedia.org/wiki/Ap%C3%A9ry%27s_constant
    //    http://society.math.ntu.edu.tw/~journal/tjm/V4N4/tjm0012_3.pdf
    //    http://www.numberworld.org/digits/Zeta(3)/
    //
    public final EFP setapery () {
      epbFpsr |= EPB_FPSR_X2;  //不正確な結果
      return this.sete (ROUNDED_APERY[epbRoundingMode]).finish ();
    }  //efp.setapery()

    //------------------------------------------------------------------------
    //y = y.setcatalan ()
    //  y=G
    //  カタランの定数 Catalan's_constant
    //
    //  式
    //    G=beta(2)
    //     =sum[n=0..∞]{(-1)^n/(2*n+1)^2}
    //     =1/1^2-1/3^2+1/5^2-1/7^2+1/9^2-1/11^2+1/13^2-1/15^2+1/17^2-1/19^2+...
    //
    //  値
    //    echo read("../misc/efp.gp");printf("%.100g\n",Catalan) | gp -q
    //    0.9159655941772190150546035149323841107741493742816721342664981196217630197762547694793565129261151062
    //
    //  参考
    //    https://en.wikipedia.org/wiki/Catalan%27s_constant
    //    http://www.numberworld.org/digits/Catalan/
    //
    public final EFP setcatalan () {
      epbFpsr |= EPB_FPSR_X2;  //不正確な結果
      return this.sete (ROUNDED_CATALAN[epbRoundingMode]).finish ();
    }  //efp.setcatalan()

    //------------------------------------------------------------------------
    //y = y.setd (d)
    //y = y.setd01 (b, a)
    //y = y.setd01 (ib, ia)
    //y = y.setd01 (l)
    //  double代入
    //  丸め処理を行わない
    //
    public final EFP setd (double d) {
      return setd01 (Double.doubleToLongBits (d));
    }  //efp.setd(double)
    public final EFP setd01 (byte[] b, int a) {
      return setd01 ((long) b[a] << 56 |
                     (long) (0xff & b[a + 1]) << 48 |
                     (long) (0xff & b[a + 2]) << 40 |
                     (long) (0xff & b[a + 3]) << 32 |
                     (long) (0xff & b[a + 4]) << 24 |
                     (long) (0xff & b[a + 5]) << 16 |
                     (long) (0xff & b[a + 6]) << 8 |
                     (long) (0xff & b[a + 7]));
    }  //efp.setd01(byte[],int)
    public final EFP setd01 (int[] ib, int ia) {
      return setd01 ((long) ib[ia] << 32 |
                     (0xffffffffL & ib[ia + 1]));
    }  //efp.setd012(int[],int)
    public final EFP setd01 (long l) {
      int zf = (int) (l >>> 32) & M;  //符号
      int ze = ((int) (l >>> 52) & 0x7ff) - 1023;  //指数部
      long zd = 0L;
      l &= -1L >>> 12;  //仮数部の小数部。doubleは正規化されているとき整数部が省略されているので後で先頭に1を付け足す必要がある
      if (ze == 1024) {  //±Inf,NaN
        if (l == 0L) {  //±Inf
          zf |= I;
        } else {  //NaN
          if (l << 12 >= 0L) {  //SNaN
            epbFpsr |= EPB_FPSR_SN;  //シグナリングNaN
            epbExceptionOperandExponent = 0x7fff << 16;
            epbExceptionOperandMantissa = 0xbfffffffffffffffL;
          }
          zf = N;
        }
      } else if (ze >= -1022) {  //正規化数
        zd = MSB | l << 11;  //整数部の1を付け足す
      } else if (l == 0L) {  //±0
        zf |= Z;
      } else {  //非正規化数
        int o = Long.numberOfLeadingZeros (l);
        ze -= o - 12;
        zd = l << o;  //非正規化数は整数部が存在しない
      }
      this.flg = zf;
      this.epp = ze;
      this.dvl = zd;
      this.cvl = 0L;
      //非正規化数でもアンダーフロー(UF)をセットしない
      //丸めない
      return this;
    }  //efp.setd01(long)

    //------------------------------------------------------------------------
    //y = y.sete (x)
    //  y=x
    //  EFP代入
    //  コピーするだけ
    //  丸め処理を行わない
    //
    public final EFP sete (EFP x) {
      this.flg = x.flg;
      this.epp = x.epp;
      this.dvl = x.dvl;
      this.cvl = x.cvl;
      return this;
    }  //efp.sete(EFP)

    //------------------------------------------------------------------------
    //y = y.seteuler ()
    //  y=γ
    //  オイラー・マスケローニ定数 Euler-Mascheroni constant
    //
    //  式
    //    γ=lim[n→∞]{sum[k=1..∞]{1/k}-log(n)}
    //
    //  値
    //    echo read("../misc/efp.gp");printf("%.100g\n",Euler) | gp -q
    //    0.5772156649015328606065120900824024310421593359399235988057672348848677267776646709369470632917467495
    //
    //  参考
    //    https://ja.wikipedia.org/wiki/%E3%82%AA%E3%82%A4%E3%83%A9%E3%83%BC%E3%81%AE%E5%AE%9A%E6%95%B0
    //    https://en.wikipedia.org/wiki/Euler%E2%80%93Mascheroni_constant
    //    http://www.numberworld.org/digits/EulerGamma/
    //
    public final EFP seteuler () {
      epbFpsr |= EPB_FPSR_X2;  //不正確な結果
      return this.sete (ROUNDED_EULER[epbRoundingMode]).finish ();
    }  //efp.seteuler()

    //------------------------------------------------------------------------
    //y = y.setf (f)
    //y = y.setf0 (b, a)
    //y = y.setf0 (ib, ia)
    //y = y.setf0 (i)
    //  float代入
    //  丸め処理を行わない
    //
    public final EFP setf (float f) {
      return setf0 (Float.floatToIntBits (f));
    }  //efp.setf(float)
    public final EFP setf0 (byte[] b, int a) {
      return setf0 (b[a] << 24 |
                    (0xff & b[a + 1]) << 16 |
                    (0xff & b[a + 2]) << 8 |
                    (0xff & b[a + 3]));
    }  //efp.setf0(byte[],int)
    public final EFP setf0 (int[] ib, int ia) {
      return setf0 (ib[ia]);
    }  //efp.setf0(int[],int)
    public final EFP setf0 (int i) {
      int zf = i & M;  //符号
      int ze = (i >>> 23 & 0xff) - 127;  //指数部
      long zd = 0L;
      i &= -1 >>> 9;  //仮数部の小数部。floatは正規化されているとき整数部が省略されているので後で先頭に1を付け足す必要がある
      if (ze == 128) {  //±Inf,NaN
        if (i == 0) {  //±Inf
          zf |= I;
        } else {  //NaN
          if (i << 9 >= 0) {  //SNaN
            epbFpsr |= EPB_FPSR_SN;  //シグナリングNaN
            epbExceptionOperandExponent = 0x7fff << 16;
            epbExceptionOperandMantissa = 0xbfffffffffffffffL;
          }
          zf = N;
        }
      } else if (ze >= -126) {  //正規化数
        zd = (long) (1 << 23 | i) << 32 + 8;  //整数部の1を付け足す
      } else if (i == 0) {  //±0
        zf |= Z;
      } else {  //非正規化数
        int o = Integer.numberOfLeadingZeros (i);
        ze -= o - 9;
        zd = (long) i << 32 + o;  //非正規化数は整数部が存在しない
      }
      this.flg = zf;
      this.epp = ze;
      this.dvl = zd;
      this.cvl = 0L;
      //非正規化数でもアンダーフロー(UF)をセットしない
      //丸めない
      return this;
    }  //efp.setf0(float)

    //------------------------------------------------------------------------
    //y = y.seti (i)
    //  int代入
    //
    public final EFP seti (int i) {
      if (i == 0) {
        this.flg = P | Z;  //+0
        return this;
      }
      int zf = P;
      if (i < 0) {  //x<0
        zf = M;
        i = -i;
      }
      int ze = 31 - Integer.numberOfLeadingZeros (i);
      long zd = (long) i << 63 - ze;  //0x80000000のとき1拡張になるが余分な1は押し出されるのでマスクは不要
      return this.finish (zf, ze, zd, 0L, 0L);
    }  //efp.seti(int)

    //------------------------------------------------------------------------
    //y = y.setinf ()
    //  +Inf代入
    //
    public final EFP setinf () {
      this.flg = P | I;
      //this.epp = 0;
      //this.dvl = 0L;
      //this.cvl = 0L;
      return this;
    }  //efp.setinf()

    //------------------------------------------------------------------------
    //y = y.setl (l)
    //  long代入
    //
    public final EFP setl (long l) {
      if (l == 0L) {
        this.flg = P | Z;  //+0
        return this;
      }
      int zf = P;
      if (l < 0L) {  //x<0
        zf = M;
        l = -l;
      }
      int ze = 63 - Long.numberOfLeadingZeros (l);
      long zd = l << ~ze;
      return this.finish (zf, ze, zd, 0L, 0L);
    }  //efp.setl(long)

    //------------------------------------------------------------------------
    //y = y.setmax ()
    //  最大値代入
    //
    //  +Infの次に大きい表現可能な値
    //
    public final EFP setmax () {
      return this.finish (P, 32767, 0xffffffffffffffffL, 0xffffffffffffffffL << 128 - LEN, 0L);
    }  //efp.setmax()

    //------------------------------------------------------------------------
    //y = y.setmin ()
    //  最小値代入
    //
    //  -Infの次に小さい表現可能な値
    //
    public final EFP setmin () {
      return this.finish (M, -32767, MSB, 0L, 0L);
    }  //efp.setmin()

    //------------------------------------------------------------------------
    //y = y.setnan ()
    //  NaN代入
    //
    public final EFP setnan () {
      this.flg = N;
      //this.epp = 0;
      //this.dvl = 0L;
      //this.cvl = 0L;
      return this;
    }  //efp.setnan()

    //------------------------------------------------------------------------
    //y = y.setnapier ()
    //  y=e
    //  ネイピア数 Napier's constant
    //
    //  式
    //    e=sum[n=0..∞]{1/n!}
    //
    //  値
    //    echo read("../misc/efp.gp");printf("%.100g\n",exp(1)) | gp -q
    //    2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427
    //
    //  参考
    //    https://ja.wikipedia.org/wiki/%E3%83%8D%E3%82%A4%E3%83%94%E3%82%A2%E6%95%B0
    //    https://en.wikipedia.org/wiki/E_(mathematical_constant)
    //    http://www.numberworld.org/digits/E/
    //
    public final EFP setnapier () {
      epbFpsr |= EPB_FPSR_X2;  //不正確な結果
      return this.sete (ROUNDED_NAPIER[epbRoundingMode]).finish ();
    }  //efp.setnapier()

    //------------------------------------------------------------------------
    //y = y.setp012 (b, a)
    //y = y.setp012 (ib, ia)
    //y = y.setp012 (i, l)
    //  packed代入
    //
    public final EFP setp012 (byte[] b, int a) {
      return setp012 (b[a] << 24 |
                      (0xff & b[a + 1]) << 16 |
                      (0xff & b[a + 2]) << 8 |
                      (0xff & b[a + 3]),
                      (long) b[a + 4] << 56 |
                      (long) (0xff & b[a + 5]) << 48 |
                      (long) (0xff & b[a + 6]) << 40 |
                      (long) (0xff & b[a + 7]) << 32 |
                      (long) (0xff & b[a + 8]) << 24 |
                      (long) (0xff & b[a + 9]) << 16 |
                      (long) (0xff & b[a + 10]) << 8 |
                      (long) (0xff & b[a + 11]));
    }  //efp.setp012(byte[],int)
    public final EFP setp012 (int[] ib, int ia) {
      return setp012 (ib[ia],
                      (long) ib[ia + 1] << 32 |
                      (0xffffffffL & ib[ia + 2]));
    }  //efp.setp012(int[],int)
    public final EFP setp012 (int u, long v) {
      int zf = u & M;  //仮数部の符号
      int e = XEiJ.FMT_DCB4[u >>> 16 & 0xfff];  //指数部
      int m0 = XEiJ.FMT_DCB4[u & 0x000f];  //整数部
      int m1 = XEiJ.FMT_DCB4[(char) (v >>> 48)];  //小数部
      int m2 = XEiJ.FMT_DCB4[(char) (v >>> 32)];
      int m3 = XEiJ.FMT_DCB4[(char) (v >>> 16)];
      int m4 = XEiJ.FMT_DCB4[(char)  v        ];
      {
        int t = m0 | m1 | m2 | m3 | m4;
        if ((u & 0x30000000) != 0 ||  //±Inf,NaN
            (e | t) < 0) {  //BCDに0..9以外の文字がある
          if (v == 0L) {  //±Inf
            this.flg = zf | I;
          } else {  //NaN
            if (v << 1 >= 0L) {  //SNaN
              epbFpsr |= EPB_FPSR_SN;  //シグナリングNaN
              epbExceptionOperandExponent = 0x7fff << 16;
              epbExceptionOperandMantissa = 0xbfffffffffffffffL;
            }
            this.flg = N;
          }
          return this;
        }
        if (t == 0) {  //整数部と小数部がすべて0
          this.flg = zf | Z;  //±0
          return this;
        }
      }
      //±0,±Inf,NaN以外
      //FPSRを保存する
      int savedMode = epbRoundingMode;
      int savedFpsr = epbFpsr;
      epbFpsr = 0;
      //仮数部を変換する
      this.inner ();
      EFP t = new EFP ();
      this.setl ((long) (m0 * 100000000 + m1 * 10000 + m2)).imul (TENXP3).iadd (t.setl ((long) (m3 * 10000 + m4)));  //仮数部
      //符号を付ける
      //  符号を付けてから丸めないとRMとRPが逆になってしまう
      this.flg |= zf;
      //指数部を変換する
      if (u << 1 < 0) {  //指数部の符号
        e = -e;
      }
      e -= 16;  //小数点以下の桁数
      if (e < 0) {  //10^-eで割る
        e = -e;
        t.set1 ();
        for (int i = 0; e != 0; i++, e >>>= 1) {
          if ((e & 1) != 0) {
            t.imul (EFP_TEN_POWER_P[i]);
          }
        }
        epbRoundingPrec = EPB_PREC_EXD;
        epbRoundingMode = savedMode;
        this.div (t);
      } else {  //10^eを掛ける
        t.set1 ();
        for (int i = 0; e != 0; i++, e >>>= 1) {
          if ((e & 1) != 0) {
            t.imul (EFP_TEN_POWER_P[i]);
          }
        }
        epbRoundingPrec = EPB_PREC_EXD;
        epbRoundingMode = savedMode;
        this.mul (t);
      }
      this.outer ();
      //基数変換で生じたX2をX1に移す
      epbFpsr = savedFpsr | epbFpsr >>> 1 & EPB_FPSR_X1;
      //丸める
      //  丸めで生じたOF,UF,X2はそのまま返す
      return this.finish ();
    }  //efp.setp012(int,long)

    //------------------------------------------------------------------------
    //y = y.setpi ()
    //  y=pi
    //  円周率
    //
    //  式
    //    Fast multiple-precision evaluation of elementary functions (1976)
    //      http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.98.4721
    //    A=1
    //    B=2^(-1/2)
    //    T=1/4
    //    X=1
    //    while A-B>2^(-n) {
    //      Y=A
    //      A=(A+B)/2
    //      B=sqrt(B*Y)
    //      T=T-X*(A-Y)^2
    //      X=2*X
    //    }
    //    return A^2/T [or, better, (A+B)^2/(4*T)]
    //
    //    AGMアルゴリズム
    //      http://www.kurims.kyoto-u.ac.jp/~ooura/pi_fft-j.html
    //    ---- a formula based on the AGM (Arithmetic-Geometric Mean) ----
    //        c = sqrt(0.125);
    //        a = 1 + 3 * c;
    //        b = sqrt(a);
    //        e = b - 0.625;
    //        b = 2 * b;
    //        c = e - c;
    //        a = a + e;
    //        npow = 4;
    //        do {
    //            npow = 2 * npow;
    //            e = (a + b) / 2;
    //            b = sqrt(a * b);
    //            e = e - b;
    //            b = 2 * b;
    //            c = c - e;
    //            a = e + b;
    //        } while (e > SQRT_SQRT_EPSILON);
    //        e = e * e / 4;
    //        a = a + b;
    //        pi = (a * a - e - e / 2) / (a * c - e) / npow;
    //      ---- modification ----
    //        This is a modified version of Gauss-Legendre formula
    //        (by T.Ooura). It is faster than original version.
    //
    //  値
    //    echo read("../misc/efp.gp");printf("%.100g\n",Pi) | gp -q
    //    3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068
    //
    //  参考
    //    https://ja.wikipedia.org/wiki/%E5%86%86%E5%91%A8%E7%8E%87
    //    https://en.wikipedia.org/wiki/Pi
    //    http://www.numberworld.org/digits/Pi/
    //
    public final EFP setpi () {
      epbFpsr |= EPB_FPSR_X2;  //不正確な結果
      return this.sete (ROUNDED_PI[epbRoundingMode]).finish ();
    }  //efp.setpi()

    //------------------------------------------------------------------------
    //y = y.setx012 (b, a)
    //y = y.setx012 (ib, ia)
    //y = y.setx012 (i, l)
    //  extended代入
    //  丸め処理を行わない
    //
    public final EFP setx012 (byte[] b, int a) {
      return setx012 (b[a] << 24 |
                      (0xff & b[a + 1]) << 16 |
                      (0xff & b[a + 2]) << 8 |
                      (0xff & b[a + 3]),
                      (long) b[a + 4] << 56 |
                      (long) (0xff & b[a + 5]) << 48 |
                      (long) (0xff & b[a + 6]) << 40 |
                      (long) (0xff & b[a + 7]) << 32 |
                      (long) (0xff & b[a + 8]) << 24 |
                      (long) (0xff & b[a + 9]) << 16 |
                      (long) (0xff & b[a + 10]) << 8 |
                      (long) (0xff & b[a + 11]));
    }  //efp.setx012(byte[],int)
    public final EFP setx012 (int[] ib, int ia) {
      return setx012 (ib[ia],
                      (long) ib[ia + 1] << 32 |
                      (0xffffffffL & ib[ia + 2]));
    }  //efp.setx012(int[],int)
    public final EFP setx012 (int i, long l) {
      int zf = i & M;  //符号
      int ze = (i >>> 16 & 32767) - 16383;  //指数部
      if (ze == 16384) {  //±Inf,NaN
        if (l == 0L) {  //±Inf
          this.flg = zf | I;
        } else {  //NaN
          if (l << 1 >= 0L) {  //SNaN
            epbFpsr |= EPB_FPSR_SN;  //シグナリングNaN
            epbExceptionOperandExponent = 0x7fff << 16;
            epbExceptionOperandMantissa = 0xbfffffffffffffffL;
          }
          this.flg = N;
        }
        return this;
      }
      if (l == 0L) {  //±0
        this.flg = zf | Z;
        return this;
      }
      if (l >= 0L) {  //未正規化数または非正規化数
        int o = Long.numberOfLeadingZeros (l);  //1..63
        ze -= o;
        l <<= o;
      }
      this.flg = zf;
      this.epp = ze;
      this.dvl = l;
      this.cvl = 0L;
      //非正規化数でもアンダーフロー(UF)をセットしない
      //丸めない
      return this;
    }  //efp.setx012(int,long)

    //------------------------------------------------------------------------
    //y = y.sety012 (b, a)
    //y = y.sety012 (ib, ia)
    //y = y.sety012 (i, l)
    //  triple代入
    //  丸め処理を行わない
    //
    public final EFP sety012 (byte[] b, int a) {
      return sety012 (b[a] << 24 |
                      (0xff & b[a + 1]) << 16 |
                      (0xff & b[a + 2]) << 8 |
                      (0xff & b[a + 3]),
                      (long) b[a + 4] << 56 |
                      (long) (0xff & b[a + 5]) << 48 |
                      (long) (0xff & b[a + 6]) << 40 |
                      (long) (0xff & b[a + 7]) << 32 |
                      (long) (0xff & b[a + 8]) << 24 |
                      (long) (0xff & b[a + 9]) << 16 |
                      (long) (0xff & b[a + 10]) << 8 |
                      (long) (0xff & b[a + 11]));
    }  //efp.sety012(byte[],int)
    public final EFP sety012 (int[] ib, int ia) {
      return sety012 (ib[ia],
                      (long) ib[ia + 1] << 32 |
                      (0xffffffffL & ib[ia + 2]));
    }  //efp.sety012(int[],int)
    public final EFP sety012 (int i, long l) {
      int zf = i & M;  //符号
      int ze = (i >>> 16 & 32767) - 16383;  //指数部
      if (ze == 16384) {  //±Inf,NaN
        if (l == 0L) {  //±Inf
          this.flg = zf | I;
        } else {  //NaN
          if (l << 1 >= 0L) {  //SNaN
            epbFpsr |= EPB_FPSR_SN;  //シグナリングNaN
            epbExceptionOperandExponent = 0x7fff << 16;
            epbExceptionOperandMantissa = 0xbfffffffffffffffL;
          }
          this.flg = N;
        }
        return this;
      }
      long m = (long) i << 48;  //仮数部の下位16bit
      if (l == 0L && m == 0L) {  //  //±0
        this.flg = zf | Z;
        return this;
      }
      if (l >= 0L) {  //未正規化数または非正規化数
        if (l != 0L) {
          int o = Long.numberOfLeadingZeros (l);  //1..63
          ze -= o;
          l = l << o | m >>> -o;
          m <<= o;
        } else {
          int o = 64 + Long.numberOfLeadingZeros (m);  //64..79
          ze -= o;
          l = m << o;
          m = 0L;
        }
      }
      this.flg = zf;
      this.epp = ze;
      this.dvl = l;
      this.cvl = m;
      //非正規化数でもアンダーフロー(UF)をセットしない
      //丸めない
      return this;
    }  //efp.sety012(int,long)

    //------------------------------------------------------------------------
    //x = x.sgn ()
    //  x=x<=>0
    //y = y.sgn (x)
    //  y=x<=>0
    //  符号
    //
    //  グラフ
    //    perl -e "use Graph;$g=new Graph();$g->grid();$g->func(sub{$_[0]<=>0});print$g"
    //    echo read("../misc/efp.gp");graph(sign) | gp -q
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       *****************************************
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +---------+---------+---------+---------*---------+---------+---------+---------+
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    *****************************************                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //
    //  isNaN(x)||x==0?x:x>0?1:-1
    //
    //  NaNの扱い
    //    NaNのときはNaNを返す
    //
    //  ±0の扱い
    //    ±0のときは±0を符号を付けたまま返す
    //
    public final EFP sgn () {
      return this.sgn (this);
    }  //efp.sgn()
    public final EFP sgn (EFP x) {
      int xf = x.flg;
      if ((xf & (Z | N)) != 0) {  //±0,NaN
        this.flg = xf;
      } else {  //±0,NaN以外
        this.flg = xf & M;  //sgn(±Inf)=±1,sgn(±x)=±1
        this.epp = 0;
        this.dvl = MSB;
        this.cvl = 0L;
      }
      return this;
    }  //efp.sgn(EFP)

    //------------------------------------------------------------------------
    //x = x.sgnsub (y)
    //  x=x<=>y
    //z = z.sgnsub (x, y)
    //  z=x<=>y
    //  比較
    //
    //  -Inf<-x<-0==+0<+x<+Inf
    //
    //  x.sub(y).sgn()と同じ結果を短い時間で返す
    //    仮数部を比較する必要があるのはフラグと指数部が一致している場合だけ
    //    仮数部を比較する場合も減算結果を正規化する必要がない
    //
    //  結果をbooleanで返す関数の代用にはならないことに注意
    //    z.sgnsub(x,y)がNaNを返すとき結果をbooleanで返す関数ではtrueにしなければならない場合とfalseにしなければならない場合がある
    //
    //  NaNの扱い
    //    どちらかがNaNのときはNaNを返す
    //    x.cmp(y)はどちらかがNaNのときに0を返す
    //
    //  ±Infの扱い
    //    +Inf<=>+Infまたは-Inf<=>-InfのときはNaNを返す
    //
    //  ±0の扱い
    //    両方が±0のときは符号に関係なく+0を返す
    //
    //  メモ
    //    EFPではインスタンスのフラグがコンディションコードを兼ねているので純粋にコンディションコードだけを返すメソッドは作れない
    //    フラグを書き換えると値が変わってしまう
    //
    public final EFP sgnsub (EFP y) {
      return this.sgnsub (this, y);
    }  //efp.sgnsub(EFP)
    public final EFP sgnsub (EFP x, EFP y) {
      int xf = x.flg;
      int yf = y.flg;
      if ((xf | yf) << 1 != 0) {  //どちらかが±0,±Inf,NaN
        if ((xf & yf) << 1 < 0 && xf == yf) {  //両方±0で符号が同じとき+0
          this.flg = P | Z;
        } else if ((xf & yf) << 2 < 0 && xf == yf ||  //両方±Infで符号が同じときNaN
                   (xf | yf) << 3 < 0) {  //どちらかがNaNのときNaN
          this.flg = N;
        } else if ((xf << 1 | yf << 2) < 0) {  //xが±0またはyが±Infのときsgn(-y)
          if (yf << 1 < 0) {
            this.flg = yf ^ M;
          } else {
            this.flg = yf & M ^ M;
            this.epp = 0;
            this.dvl = MSB;
            this.cvl = 0L;
          }
        } else {  //xが±Infまたはyが±0のときsgn(x)
          this.flg = xf & M;
          this.epp = 0;
          this.dvl = MSB;
          this.cvl = 0L;
        }
      } else if (xf != yf) {  //両方±0,±Inf,NaN以外で符号が違う
        this.flg = xf >= 0 ? P : M;
        this.epp = 0;
        this.dvl = MSB;
        this.cvl = 0L;
      } else {  //両方±0,±Inf,NaN以外で符号が同じ
        int s;
        long t;
        s = (xf >= 0 ? 1 : -1) * ((s = x.epp - y.epp) != 0 ? s >= 0 ? 1 : -1 :
                                  (t = x.dvl - y.dvl) != 0L ? t >= 0L ? 1 : -1 :
                                  (t = (x.cvl >>> 1) - (y.cvl >>> 1)) != 0L ? t >= 0L ? 1 : -1 :
                                  0);
        if (s != 0) {  //値が違う
          this.flg = s >= 0 ? P : M;
          this.epp = 0;
          this.dvl = MSB;
          this.cvl = 0L;
        } else {  //値が同じ
          this.flg = P | Z;  //+0
        }
      }
      return this;
    }  //efp.sgnsub(EFP,EFP)

    //------------------------------------------------------------------------
    //x = x.shl (n)
    //  x*=2^n
    //y = y.shl (x, n)
    //  y=x*2^n
    //  2^n倍(左シフト)
    //
    public final EFP shl (int n) {
      //nが大きすぎてInteger.MAX_VALUEを跨いでしまうと都合が悪いのでnに細工をする
      n = Math.max (-65536, Math.min (65536, n));
      return this.finish (this.flg, this.epp + n, this.dvl, this.cvl, 0L);
    }  //efp.shl(int)
    public final EFP shl (EFP x, int n) {
      //nが大きすぎてInteger.MAX_VALUEを跨いでしまうと都合が悪いのでnに細工をする
      n = Math.max (-65536, Math.min (65536, n));
      return this.finish (x.flg, x.epp + n, x.dvl, x.cvl, 0L);
    }  //efp.shl(EFP,int)

    //------------------------------------------------------------------------
    //x = x.shr (n)
    //  x/=2^n
    //y = y.shr (x, n)
    //  y=x/2^n
    //  1/2^n倍(右シフト)
    //
    public final EFP shr (int n) {
      //nが大きすぎてInteger.MAX_VALUEを跨いでしまうと都合が悪いのでnに細工をする
      n = Math.max (-65536, Math.min (65536, n));
      return this.finish (this.flg, this.epp - n, this.dvl, this.cvl, 0L);
    }  //efp.shr(int)
    public final EFP shr (EFP x, int n) {
      //nが大きすぎてInteger.MAX_VALUEを跨いでしまうと都合が悪いのでnに細工をする
      n = Math.max (-65536, Math.min (65536, n));
      return this.finish (x.flg, x.epp - n, x.dvl, x.cvl, 0L);
    }  //efp.shr(EFP,int)

    //------------------------------------------------------------------------
    //x = x.sin ()
    //  x=sin(x)
    //y = y.sin (x)
    //  y=sin(x)
    //  正弦 sine サイン
    //
    //  グラフ
    //    perl -e "use Math::Trig;use Graph;$g=new Graph();$g->grid();$g->func(sub{sin($_[0])});print$g"
    //    echo read("../misc/efp.gp");graph(sin) | gp -q
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +          **********                   +
    //    **                                      |       ****        *****               |
    //    |***                                    |    ****               ***             |
    //    |  ****                                 |  ***                    ***           |
    //    |     ***                               |***                        ***         |
    //    +-------***---------+---------+--------***--------+---------+---------***-------+
    //    |         ***                        ***|                               ***     |
    //    |           ***                    ***  |                                 ****  |
    //    |             ***               ****    |                                    ***|
    //    |               *****        ****       |                                      **
    //    +                   **********          +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //
    //  定義域
    //    -inf<=x<=inf
    //
    //  値域
    //    -1<=sin(x)<=1
    //
    //  三角関数のとの関係
    //    sin(x)=2*tan(x/2)/(1+tan(x/2)^2)
    //
    //  変数変換
    //    収束を速くするために|x|<=pi/4にする
    //    sin(x)=cos(x-pi/2)
    //          =-sin(x-pi)
    //          =-cos(x-3*pi/2)
    //          =sin(x-2*pi)
    //                  cos(x-pi/2)
    //                             k=1
    //                       │    ←
    //            k=2↓\    │    /
    //                   \  │  /
    //                     \│/
    //    -sin(x-pi) ────・──── sin(x)
    //                     /│\
    //                   /  │  \
    //                 /    │    \↑k=0
    //                 →    │
    //                k=3
    //                -cos(x-3*pi/2)
    //
    //  テイラー展開
    //    sin(x)=x-x^3/3!+x^5/5!-x^7/7!...
    //    f(n,x)=sum(k=0,n,(-1)^k*x^(2*k+1)/(2*k+1)!)
    //    除算は不要
    //
    //  チェビシェフ展開
    //    テイラー展開よりも収束が速い
    //    除算は不要
    //
    //  CORDIC
    //    固定小数点演算用
    //    浮動小数点演算では結果の指数部が小さいとき有効桁数が不足する
    //    桁数の少ない浮動小数点演算では加減算と乗算のコストがあまり変わらないので乗算が減っても加減算が増え過ぎるとかえって遅くなる
    //    参考
    //      サルでも分かるCORDICアルゴリズム
    //      http://teamcoil.sp.u-tokai.ac.jp/calculator/100224/
    //
    //  sin(x)
    //    echo read("../misc/efp.gp");eval("f(n,x)=sum(k=0,n,(-1)^k/(2*k+1)!*x^(2*k+1))");for(n=0,26,printf("%4d",floor(closeness(sin,f(n,x),-Pi/4,Pi/4,10000)))) | gp -q
    //    echo read("../misc/efp.gp");eval("f(x)=sin(x)");a=-Pi/4;b=-a;forstep(n=1,27,2,printf("%4d",floor(closeness(f,chebyshev(f,a,b,n),a,b,10000)))) | gp -q
    //                次数   1   3   5   7   9  11  13  15  17  19  21  23  25  27  29  31  33  35  37  39  41  43  45  47  49  51  53
    //        テイラー展開   3   8  14  21  28  36  44  53  62  72  81  91 102 112 122 133 144 155 166 178 189 201 213 225 237 249 261
    //    チェビシェフ展開
    //        [-pi/4,pi/4]   3  10  17  26  35  45  55  65  76  88  99 111 123 135
    //
    public final EFP sin () {
      return this.sin (this);
    }  //efp.sin()
    public final EFP sin (EFP x) {
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        if (xf << 1 < 0) {  //±0
          this.flg = xf;  //sin(±0)=±0
        } else if (xf << 2 < 0) {  //±Inf
          epbFpsr |= EPB_FPSR_OE;
          epbExceptionOperandExponent = xf & M | 0x7fff << 16;
          epbExceptionOperandMantissa = 0x0000000000000000L;
          this.flg = N;  //sin(±Inf)=NaN
        } else {  //NaN
          this.flg = N;  //sin(NaN)=NaN
        }
        return this;
      }
      //±0,±Inf,NaN以外
      int savedFpsr = epbFpsr;
      this.inner ();
      if (this == x) {
        x = new EFP (x);
      }
      EFP u = new EFP ();
      EFP u2 = new EFP ();
      int k = u.ieeerempi2 (x);  //-pi/2<=u<=pi/2。kはx-uの象限
      if (false) {  //テイラー展開
        EFP s = new EFP ();
        EFP t = new EFP ();
        u2.isqu (u);  //u^2
        if ((k & 1) == 0) {  //sin
          //s.sete (u);  //(-1)^k*x^(2*k+1)/(2*k+1)!
          s.flg = u.flg;
          s.epp = u.epp;
          s.dvl = u.dvl;
          s.cvl = u.cvl;
          //t.set0 ();
          t.flg = P | Z;
          //this.sete (s);
          this.flg = s.flg;
          this.epp = s.epp;
          this.dvl = s.dvl;
          this.cvl = s.cvl;
          for (int twok1 = 3; this.ne (t); twok1 += 2) {  //2*k+1
            s.imul (u2).divi ((1 - twok1) * twok1);  //(-1)^k*x^(2*k+1)/(2*k+1)!
            //t.sete (this);
            t.flg = this.flg;
            t.epp = this.epp;
            t.dvl = this.dvl;
            t.cvl = this.cvl;
            this.iadd (s);
          }
        } else {  //cos
          //s.set1 ();  //(-1)^k*x^(2*k)/(2*k)!
          s.flg = P;
          s.epp = 0;
          s.dvl = MSB;
          s.cvl = 0L;
          //t.set0 ();
          t.flg = P | Z;
          //this.sete (s);
          this.flg = s.flg;
          this.epp = s.epp;
          this.dvl = s.dvl;
          this.cvl = s.cvl;
          for (int twok = 2; this.ne (t); twok += 2) {  //2*k
            s.imul (u2).divi ((1 - twok) * twok);  //(-1)^k*x^(2*k)/(2*k)!
            //t.sete (this);
            t.flg = this.flg;
            t.epp = this.epp;
            t.dvl = this.dvl;
            t.cvl = this.cvl;
            this.iadd (s);
          }
        }
      } else {  //チェビシェフ展開
        if ((k & 1) == 0) {  //sin
          u2.isqu (u);  //u^2
          this.imul (SIN_C21, u2)
            .iadd (SIN_C19).imul (u2)
              .iadd (SIN_C17).imul (u2)
                .iadd (SIN_C15).imul (u2)
                  .iadd (SIN_C13).imul (u2)
                    .iadd (SIN_C11).imul (u2)
                      .iadd (SIN_C9).imul (u2)
                        .iadd (SIN_C7).imul (u2)
                          .iadd (SIN_C5).imul (u2)
                            .iadd (SIN_C3).imul (u2)
                              .iadd (SIN_C1).imul (u);
        } else {  //cos
          u2.isqu (u);  //u^2
          this.imul (COS_C20, u2)
            .iadd (COS_C18).imul (u2)
              .iadd (COS_C16).imul (u2)
                .iadd (COS_C14).imul (u2)
                  .iadd (COS_C12).imul (u2)
                    .iadd (COS_C10).imul (u2)
                      .iadd (COS_C8).imul (u2)
                        .iadd (COS_C6).imul (u2)
                          .iadd (COS_C4).imul (u2)
                            .iadd (COS_C2).imul (u2)
                              .iadd (COS_C0);
        }
      }
      this.outer ().neg (k << 30 < 0);
      //  n*pi/2はn==0を除いて正確に表現できないので、
      //    RZまたはRPでsin(x)およびcos(x)が-1になることはあり得ない
      //    RZまたはRMでsin(x)およびcos(x)がcos(0)以外で+1になることはあり得ない
      if (this.flg << 1 == 0 && this.epp == 0) {  //結果が±1
        if (this.flg < 0) {  //結果が-1
          if (epbRoundingMode == EPB_MODE_RZ || epbRoundingMode == EPB_MODE_RP) {  //RZまたはRPで結果が-1
            this.sete (NEXTUP_MINUSONE[epbRoundingPrec]);
          }
        } else {  //結果が+1
          if (epbRoundingMode == EPB_MODE_RZ || epbRoundingMode == EPB_MODE_RM) {  //RZまたはRMで結果が+1
            this.sete (NEXTDOWN_PLUSONE[epbRoundingPrec]);
          }
        }
      }
      return this.originUpperLower (x).correctUnderflow (savedFpsr);
    }  //efp.sin(EFP)

    //------------------------------------------------------------------------
    //x = x.sinh ()
    //  x=sinh(x)
    //y = y.sinh (x)
    //  y=sinh(x)
    //  双曲線正弦 hyperbolic sine ハイパボリックサイン
    //
    //  グラフ
    //    perl -e "use Math::Trig;use Graph;$g=new Graph();$g->grid();$g->func(sub{sinh($_[0])});print$g"
    //    echo read("../misc/efp.gp");graph(sinh) | gp -q
    //    +---------+---------+---------+---------+---------+---------+*--------+---------+
    //    |                                       |                   **                  |
    //    |                                       |                   *                   |
    //    |                                       |                  **                   |
    //    |                                       |                 **                    |
    //    +                                       +                 *                     +
    //    |                                       |                **                     |
    //    |                                       |               **                      |
    //    |                                       |               *                       |
    //    |                                       |              **                       |
    //    +                                       +             **                        +
    //    |                                       |            **                         |
    //    |                                       |           **                          |
    //    |                                       |          **                           |
    //    |                                       |         **                            |
    //    +                                       +       ***                             +
    //    |                                       |      **                               |
    //    |                                       |    ***                                |
    //    |                                       |  ***                                  |
    //    |                                       |***                                    |
    //    +---------+---------+---------+--------***--------+---------+---------+---------+
    //    |                                    ***|                                       |
    //    |                                  ***  |                                       |
    //    |                                ***    |                                       |
    //    |                               **      |                                       |
    //    +                             ***       +                                       +
    //    |                            **         |                                       |
    //    |                           **          |                                       |
    //    |                          **           |                                       |
    //    |                         **            |                                       |
    //    +                        **             +                                       +
    //    |                       **              |                                       |
    //    |                       *               |                                       |
    //    |                      **               |                                       |
    //    |                     **                |                                       |
    //    +                     *                 +                                       +
    //    |                    **                 |                                       |
    //    |                   **                  |                                       |
    //    |                   *                   |                                       |
    //    |                  **                   |                                       |
    //    +---------+--------*+---------+---------+---------+---------+---------+---------+
    //
    //  定義域
    //    -inf<=x<=inf
    //
    //  値域
    //    -inf<=sinh(x)<=inf
    //
    //  指数関数との関係
    //    sinh(x)=(e^x-e^-x)/2
    //           =((e^x)^2-1)/(2*e^x)
    //
    //  テイラー展開
    //    sinh(x)=x+x^3/3!+x^5/5!+x^7/7!+...
    //    f(n,x)=sum(k=0,n,x^(2*k+1)/(2*k+1)!)
    //    echo read("../misc/efp.gp");eval("f(n,x)=sum(k=0,n,1/(2*k+1)!*x^(2*k+1))");a=-0.0625;b=0.0625;for(n=0,12,printf("%4d",floor(closeness(sinh,f(n,x),a,b,10000)))) | gp -q
    //       1   3   5   7   9  11  13  15  17  19  21  23  25
    //      10  22  36  50  65  80  96 112 128 145 162 179 197
    //
    //  チェビシェフ展開
    //    0の近くだけチェビシェフ展開を使う
    //    echo read("../misc/efp.gp");eval("f(x)=sinh(x)");a=-0.0625;b=0.0625;forstep(n=1,25,2,printf("%4d",floor(closeness(f,chebyshev(f,a,b,n),a,b,10000)))) | gp -q
    //       1   3   5   7   9  11  13  15  17  19  21  23  25
    //      10  24  39  55  71  88 106 124 142 161 179 199 218
    //    echo read("../misc/efp.gp");eval("f(x)=sinh(x)");a=-0.125;b=0.125;forstep(n=1,25,2,printf("%4d",floor(closeness(f,chebyshev(f,a,b,n),a,b,10000)))) | gp -q
    //       1   3   5   7   9  11  13  15  17  19  21  23  25
    //       8  20  33  47  61  76  92 108 124 141 157 175 192
    //
    public final EFP sinh () {
      return this.sinh (this);
    }  //efp.sinh()
    public final EFP sinh (EFP x) {
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        this.flg = xf;
        return this;
      }
      //±0,±Inf,NaN以外
      epbFpsr |= EPB_FPSR_X2;  //不正確な結果。オーバーフローまたはアンダーフローのときもセットされる
      epbExceptionOperandExponent = xf | 0x3fff + x.epp << 16;
      epbExceptionOperandMantissa = x.dvl;
      if (15 <= x.epp) {  //x<=-32768||32768<=x。sinh(-big)=-Inf,sinh(+big)=+Inf
        epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
        return this.sete (OVFL_RESULTS[epbRoundingPrec << 3 | epbRoundingMode << 1 | xf >>> 31]).finish ();  //±Inf
      }
      if (x.epp < -3) {  //|x|<0.125
        int savedFpsr = epbFpsr;
        this.inner ();
        if (this == x) {
          x = new EFP (x);
        }
        EFP x2 = new EFP ().isqu (x);  //x^2
        this.imul (SINH_C13, x2)
          .iadd (SINH_C11).imul (x2)
            .iadd (SINH_C9).imul (x2)
              .iadd (SINH_C7).imul (x2)
                .iadd (SINH_C5).imul (x2)
                  .iadd (SINH_C3).imul (x2)
                    .iadd (SINH_C1).outer ().mul (x);
        return this.originLowerUpper (x).correctUnderflow (savedFpsr);
      }
      //0.125<=|x|
      //  xが絶対値の大きい負数のときそのままe^xを計算するとアンダーフローして0になりさらに1/e^xがゼロ除算になる
      //  オーバーフローだけセットさせるためにxの符号を取ってからe^xを計算する
      //  丸める前に符号を付けないとRMとRPが逆になってしまうことに注意する
      this.inner ().abs (x).exp ();  //e^|x|
      this.sub (new EFP ().rcp (this)).div2 ().outer ().neg (xf < 0);  //(e^|x|-e^-|x|)/2
      if (this.flg << 2 < 0) {
        epbFpsr |= EPB_FPSR_OF;  //オーバーフロー
        return this.sete (OVFL_RESULTS[epbRoundingPrec << 3 | epbRoundingMode << 1 | this.flg >>> 31]).finish ();  //±Inf
      }
      return this;
    }  //efp.sinh(EFP)

    //------------------------------------------------------------------------
    //x = x.sqrt ()
    //  x=sqrt(x)
    //y = y.sqrt (x)
    //  y=sqrt(x)
    //  1/2乗(平方根)
    //
    //  グラフ
    //    perl -e "use Graph;$g=new Graph();$g->grid();$g->func(sub{sqrt($_[0])});print$g"
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                   *****
    //    |                                       |                            ********   |
    //    |                                       |                      *******          |
    //    |                                       |                *******                |
    //    |                                       |           ******                      |
    //    +                                       +       *****                           +
    //    |                                       |    ****                               |
    //    |                                       |  ***                                  |
    //    |                                       |***                                    |
    //    |                                       **                                      |
    //    +---------+---------+---------+---------*---------+---------+---------+---------+
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //    echo read("../misc/efp.gp");graph(sqrt) | gp -q
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                   *****
    //    |                                       |                            ********   |
    //    |                                       |                      *******          |
    //    |                                       |                ******                 |
    //    |                                       |           ******                      |
    //    +                                       +       *****                           +
    //    |                                       |    ****                               |
    //    |                                       |  ***                                  |
    //    |                                       |**                                     |
    //    |                                       **                                      |
    //    +---------+---------+---------+---------*---------+---------+---------+---------+
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //
    //  変数変換
    //    EFPの指数部はdoubleに収まらない
    //    x=x'*2^(2*k)  2^0<=x'<2^2
    //    sqrt(x)=sqrt(x'*2^(2*k))
    //           =sqrt(x')*2^k
    //
    //  ニュートン法1
    //    Math.sqrt()を使ってt=sqrt(x)をdoubleの精度で求めてからニュートン法の反復を1回行う
    //    f(t)=t^2-x
    //    f'(t)=2*t
    //    t'=t-f(t)/f'(t)
    //      =t-(t^2-x)/(2*t)
    //      =(2*t^2-(t^2-x))/(2*t)
    //      =(t^2+x)/(2*t)
    //      =(t+x/t)/2
    //    除算が必要
    //
    //  ニュートン法2
    //    Math.sqrt()を使ってt=1/sqrt(x)をdoubleの精度で求めてからニュートン法の反復を1回行ってxを掛ける
    //    f(t)=1/t^2-x
    //    f'(t)=-2/t^3
    //    t1=t-f(t)/f'(t)
    //      =t-(1/t^2-x)/(-2/t^3)
    //      =t+t/2-x*t^3/2
    //      =(3*t-x*t^3)/2
    //    sqrt(x)=x*t1
    //           =x*(3*t-x*t^3)/2
    //    除算は不要
    //
    //  整数の平方根
    //    floor(sqrt(x))
    //    範囲
    //      xがs>0桁のときfloor(sqrt(x))はs+1>>1桁
    //      1<<(s-1>>1) <= floor(sqrt(x)) <= (s&1)!=0?x>>(s>>1):(1<<(s>>1))-1
    //    ニュートン法
    //      初期値
    //        t=(s&1)!=0?x>>(s>>1):(1<<(s>>1))-1
    //      反復
    //        t=floor(x/t)+t>>1
    //      tが減らなくなるまで繰り返す。最後から2番目のtがfloor(sqrt(x))
    //
    //  Math.sqrt(-0.0)はNaNにならず-0.0が返るのでこれに合わせる
    //
    //  テイラー展開
    //    x=2^(2*n)の近くはsqrt(1+x)-1のテイラー展開を使う
    //      coeff(sub(a=0,for n:=0:7 sum sub(x=a,df(sqrt(1+x)-1,x,n))/factorial(n)*(x-a)^n),x);
    //          1    - 1   1     - 5    7     - 21    33
    //      {0,---,------,----,------,-----,-------,------}
    //          2    8     16   128    256   1024    2048
    //      for n:=0:7 collect (if n=0 then 0 else (-1)^(n-1)/2^(2*n-1)*factorial(2*n-2)/factorial(n-1)/factorial(n));
    //          1    - 1   1     - 5    7     - 21    33
    //      {0,---,------,----,------,-----,-------,------}
    //          2    8     16   128    256   1024    2048
    //
    public final EFP sqrt () {
      return this.sqrt (this);
    }  //efp.sqrt()
    public final EFP sqrt (EFP x) {
      int xf = x.flg;
      if (xf != 0) {  //-x,±0,±Inf,NaN
        if (xf == M || xf == (M | I)) {  //sqrt(-x)=NaN, sqrt(-Inf)=NaN
          epbFpsr |= EPB_FPSR_OE;
          if (xf << 2 < 0) {  //-Inf
            epbExceptionOperandExponent = xf & M | 0x7fff << 16;
            epbExceptionOperandMantissa = 0x0000000000000000L;
          } else {  //-x
            epbExceptionOperandExponent = xf & M | 0x3fff + x.epp << 16;
            epbExceptionOperandMantissa = x.dvl;
          }
          this.flg = N;
        } else {
          this.flg = xf;  //sqrt(±0)=±0, sqrt(+Inf)=+Inf, sqrt(NaN)=NaN
        }
        return this;
      }
      //+x
      if (false) {  //ニュートン法。[92] 535ns
        this.inner ();
        EFP t = new EFP (ONE).max (x);
        EFP u = new EFP (x);  //thisが破壊されるのでxをコピーしておく
        EFP w = new EFP ();
        do {
          //this.sete (t);
          this.flg = t.flg;
          this.epp = t.epp;
          this.dvl = t.dvl;
          this.cvl = t.cvl;
          t.iadd (w.sete (u).div (t)).idiv2 ();  //t=(t+x/t)/2
        } while (this.gt (t));
        return this.outer ().finish ();
      } else {  //Math.sqrtを使う。[92] 70.5ns
        if (this == x) {
          x = new EFP (x);
        }
        int xe = x.epp;
        if ((xe & 1) != 0 ? (x.dvl >>> -8) == 0xFF : (x.dvl >>> -9) == 0x100) {  //仮数部が1-1/256..1+1/256のとき
          //  1-1/256=2^-1*0xFF/2^7
          //  1+1/256=2^0*0x101/2^8
          this.inner ();
          x.epp = -(xe & 1);  //指数部を-1または0にする
          x.dec ();  //1を引く
          this.imul (x, SQRT1PM1_C11).
            iadd (SQRT1PM1_C10).imul (x).
              iadd (SQRT1PM1_C9).imul (x).
                iadd (SQRT1PM1_C8).imul (x).
                  iadd (SQRT1PM1_C7).imul (x).
                    iadd (SQRT1PM1_C6).imul (x).
                      iadd (SQRT1PM1_C5).imul (x).
                        iadd (SQRT1PM1_C4).imul (x).
                          iadd (SQRT1PM1_C3).imul (x).
                            iadd (SQRT1PM1_C2).imul (x).
                              iadd (SQRT1PM1_C1).imul (x);  //テイラー展開
          this.outer ().inc ();  //1を加えながら丸める
          if (this.flg << 1 == 0) {
            //指数部を補正する
            //  分かりやすいように10進数で書く
            //         xの範囲      xの指数  sqrt(x)の範囲   sqrt(x)の指数  dec前とinc後の指数  補正値
            //    0.0099<=x<0.0100    -3     0.099<=x<0.1          -2               -1            -1
            //    0.0100<=x<0.0101    -2     0.100<=x<0.101        -1                0            -1
            //     0.099<=x<0.100     -2
            //     0.100<=x<0.101     -1
            //      0.99<=x<1         -1      0.99<=x<1            -1               -1             0
            //         1<=x<1.01       0         1<=x<1.01          0                0             0
            //       9.9<=x<10         0
            //        10<=x<10.1       1
            //        99<=x<100        1       9.9<=x<10            0               -1             1
            //       100<=x<101        2        10<=x<10.1          1                0             1
            //       990<=x<1000       2
            //      1000<=x<1010       3
            //      9900<=x<10000      3        99<=x<100           1               -1             2
            //     10000<=x<10100      4       100<=x<101           2                0             2
            this.epp += xe + 1 >> 1;  //指数部を復元する。負数の右シフトの挙動に注意。ここで指数部が範囲外になることがある
            this.finish ();
          }
          return this;
        }
        //  EFPをdoubleに変換する
        //    EFPの指数部はdoubleの指数部に収まらないので下位1bitだけ使う
        //    仮数部は上位53bitを使う
        //  Math.sqrtで53bitの平方根を求める
        //  doubleをEFPに変換する
        //    指数部に元の指数部の下位1bitを除いた残りの1/2を加える
        //  ニュートン法の反復を1回行う
        //  sqrtでは指数部が正でも負でも半分になるので丸めで制限されるまでオーバーフローもアンダーフローも発生しない
        //  丸める
        //  結果を2乗する
        //  結果の2乗を正確に表現できない場合と結果の2乗と元の値が一致しない場合はX2をセットする
        long s = Double.doubleToLongBits (Math.sqrt (Double.longBitsToDouble ((long) (1023 + (xe & 1)) << 52 | x.dvl << 1 >>> 12)));
        EFP t = new EFP (P, (int) (s >>> 52) - 1023 + (xe >> 1), MSB | s << 12 >>> 1, 0L);
        int savedFpsr = epbFpsr;
        this.inner ().div (x, t).iadd (t).outer ();
        this.epp--;  //(t+x/t)/2
        epbFpsr = 0;
        this.finish ();
        savedFpsr |= epbFpsr & (EPB_FPSR_OF | EPB_FPSR_UF);
        this.inner ();
        t.squ (this);
        this.outer ();
        if ((epbFpsr & EPB_FPSR_X2) != 0 || !t.eq (x)) {
          savedFpsr |= EPB_FPSR_X2;  //不正確な結果
          epbExceptionOperandExponent = xf | 0x3fff + x.epp << 16;
          epbExceptionOperandMantissa = x.dvl;
        }
        epbFpsr = savedFpsr;
        return this;
      }
    }  //efp.sqrt(EFP)

    //------------------------------------------------------------------------
    //x = x.squ ()
    //  x*=x
    //y = y.squ (x)
    //  y=x^2
    //  2乗
    //
    //  グラフ
    //    perl -e "use Graph;$g=new Graph();$g->grid();$g->func(sub{$_[0]**2});print$g"
    //    echo read("../misc/efp.gp");eval("squ(x)=x^2");graph(squ) | gp -q
    //    +---------+---------*---------+---------+---------+---------*---------+---------+
    //    |                   **                  |                  **                   |
    //    |                    *                  |                  *                    |
    //    |                    **                 |                 **                    |
    //    |                     *                 |                 *                     |
    //    +                     **                +                **                     +
    //    |                      **               |               **                      |
    //    |                       *               |               *                       |
    //    |                       **              |              **                       |
    //    |                        **             |             **                        |
    //    +                         *             +             *                         +
    //    |                         **            |            **                         |
    //    |                          **           |           **                          |
    //    |                           **          |          **                           |
    //    |                            **         |         **                            |
    //    +                             **        +        **                             +
    //    |                              **       |       **                              |
    //    |                               **      |      **                               |
    //    |                                ***    |    ***                                |
    //    |                                  ***  |  ***                                  |
    //    +---------+---------+---------+------*******------+---------+---------+---------+
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //
    public final EFP squ () {
      int xf = this.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        this.flg = xf << 3 < 0 ? N : xf & ~M;  //(±0)^2=+0, (±Inf)^2=+Inf, NaN^2=NaN
        return this;
      }
      //3分割する
      //  92bitの仮数部を32bit,30bit,30bitに分割する
      long zd = this.dvl;
      long zc = this.cvl;
      long zb = (zd << -2 | zc >>> 2) >>> -30;  //下位30bit
      zc = zd << 32 >>> -30;  //中位30bit
      zd >>>= 32;  //上位32bit
      //2乗する
      //  (zd*2^60+zc*2^30+zb)^2=zd^2*2^120+2*zd*zc*2^90+(2*zd*zb+zc^2)*2^60+2*zc*zb*2^30+zb^2
      long t = zb * zb;  //2^0
      long s = t & 0xffffffffL;  //sticky bit
      t = (t >>> 30) + (zc * zb << 1);  //2^30
      s |= t & 0xffffffffL;
      t = (t >>> 30) + (zd * zb << 1) + zc * zc;  //2^60
      s |= t & 0xffffffffL;
      t = (t >>> 30) + (zd * zc << 1);  //2^90
      zd = (t >>> 30) + zd * zd;  //2^120
      zc = t << -30 | s;
      int ze = this.epp << 1;
      if (zd < 0L) {
        ze++;
      } else {
        zd = zd << 1 | zc >>> -1;
        zc <<= 1;
      }
      return this.finish (P, ze, zd, zc, 0L);
    }  //efp.squ()
    public final EFP isqu () {
      int xf = this.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        this.flg = xf << 3 < 0 ? N : xf & ~M;  //(±0)^2=+0, (±Inf)^2=+Inf, NaN^2=NaN
        return this;
      }
      //3分割する
      //  92bitの仮数部を32bit,30bit,30bitに分割する
      long zd = this.dvl;
      long zc = this.cvl;
      long zb = (zd << -2 | zc >>> 2) >>> -30;  //下位30bit
      zc = zd << 32 >>> -30;  //中位30bit
      zd >>>= 32;  //上位32bit
      //2乗する
      //  (zd*2^60+zc*2^30+zb)^2=zd^2*2^120+2*zd*zc*2^90+(2*zd*zb+zc^2)*2^60+2*zc*zb*2^30+zb^2
      long t = zb * zb;  //2^0
      long s = t & 0xffffffffL;  //sticky bit
      t = (t >>> 30) + (zc * zb << 1);  //2^30
      s |= t & 0xffffffffL;
      t = (t >>> 30) + (zd * zb << 1) + zc * zc;  //2^60
      s |= t & 0xffffffffL;
      t = (t >>> 30) + (zd * zc << 1);  //2^90
      zd = (t >>> 30) + zd * zd;  //2^120
      zc = t << -30 | s;
      int ze = this.epp << 1;
      if (zd < 0L) {
        ze++;
      } else {
        zd = zd << 1 | zc >>> -1;
        zc <<= 1;
      }
      return this.ifinish (P, ze, zd, zc, 0L);
    }  //efp.isqu()
    public final EFP squ (EFP x) {
      //return this.mul (x, x);  //11.8ns
      //8.4ns
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        this.flg = xf << 3 < 0 ? N : xf & ~M;  //(±0)^2=+0, (±Inf)^2=+Inf, NaN^2=NaN
        return this;
      }
      //3分割する
      //  92bitの仮数部を32bit,30bit,30bitに分割する
      long zd = x.dvl;
      long zc = x.cvl;
      long zb = (zd << -2 | zc >>> 2) >>> -30;  //下位30bit
      zc = zd << 32 >>> -30;  //中位30bit
      zd >>>= 32;  //上位32bit
      //2乗する
      //  (zd*2^60+zc*2^30+zb)^2=zd^2*2^120+2*zd*zc*2^90+(2*zd*zb+zc^2)*2^60+2*zc*zb*2^30+zb^2
      long t = zb * zb;  //2^0
      long s = t & 0xffffffffL;  //sticky bit
      t = (t >>> 30) + (zc * zb << 1);  //2^30
      s |= t & 0xffffffffL;
      t = (t >>> 30) + (zd * zb << 1) + zc * zc;  //2^60
      s |= t & 0xffffffffL;
      t = (t >>> 30) + (zd * zc << 1);  //2^90
      zd = (t >>> 30) + zd * zd;  //2^120
      zc = t << -30 | s;
      int ze = x.epp << 1;
      if (zd < 0L) {
        ze++;
      } else {
        zd = zd << 1 | zc >>> -1;
        zc <<= 1;
      }
      return this.finish (P, ze, zd, zc, 0L);
    }  //efp.squ(EFP)
    public final EFP isqu (EFP x) {
      //return this.mul (x, x);  //11.8ns
      //8.4ns
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        this.flg = xf << 3 < 0 ? N : xf & ~M;  //(±0)^2=+0, (±Inf)^2=+Inf, NaN^2=NaN
        return this;
      }
      //3分割する
      //  92bitの仮数部を32bit,30bit,30bitに分割する
      long zd = x.dvl;
      long zc = x.cvl;
      long zb = (zd << -2 | zc >>> 2) >>> -30;  //下位30bit
      zc = zd << 32 >>> -30;  //中位30bit
      zd >>>= 32;  //上位32bit
      //2乗する
      //  (zd*2^60+zc*2^30+zb)^2=zd^2*2^120+2*zd*zc*2^90+(2*zd*zb+zc^2)*2^60+2*zc*zb*2^30+zb^2
      long t = zb * zb;  //2^0
      long s = t & 0xffffffffL;  //sticky bit
      t = (t >>> 30) + (zc * zb << 1);  //2^30
      s |= t & 0xffffffffL;
      t = (t >>> 30) + (zd * zb << 1) + zc * zc;  //2^60
      s |= t & 0xffffffffL;
      t = (t >>> 30) + (zd * zc << 1);  //2^90
      zd = (t >>> 30) + zd * zd;  //2^120
      zc = t << -30 | s;
      int ze = x.epp << 1;
      if (zd < 0L) {
        ze++;
      } else {
        zd = zd << 1 | zc >>> -1;
        zc <<= 1;
      }
      return this.ifinish (P, ze, zd, zc, 0L);
    }  //efp.isqu(EFP)

    //------------------------------------------------------------------------
    //x = x.sub (y)
    //  x-=y
    //z = z.sub (x, y)
    //  z=x-y
    //  減算
    //
    //  (xn/xd)-(yn/yd)
    //    =((xn*yd)/(xd*yd))-((xd*yn)/(xd*yd))
    //    =(xn*yd-xd*yn)/(xd*yd)
    //
    public final EFP sub (EFP y) {
      int xf = this.flg;
      int xe = this.epp;
      long xd = this.dvl;
      long xc = this.cvl;
      long xb = 0L;
      int yf = y.flg;
      if ((xf | yf) << 1 != 0) {  //どちらかが±0,±Inf,NaN
        if ((xf | yf) << 3 < 0) {  //どちらかがNaNのときNaN
          this.flg = N;
          return this;
        }
        if ((xf & yf) << 2 < 0 && xf == yf) {  //両方±Infで符号が同じときNaN
          epbFpsr |= EPB_FPSR_OE;
          epbExceptionOperandExponent = yf & M | 0x7fff << 16;
          epbExceptionOperandMantissa = 0x0000000000000000L;
          this.flg = N;
          return this;
        }
        if ((xf & yf) << 1 < 0 && xf == yf) {  //両方±0で符号が同じとき
          this.flg = epbRoundingMode == EPB_MODE_RM ? M | Z : P | Z;  //RMのとき-0,それ以外は+0
          return this;
        }
        if (xf << 1 < 0 || yf << 2 < 0) {  //xが±0またはyが±Infのとき-y
          xf = yf ^ M;
          xe = y.epp;
          xd = y.dvl;
          xc = y.cvl;
        }
        //xが±Infまたはyが±0のときx
      } else {  //両方±0,±Inf,NaN以外
        //減算なのでyの符号を反転して加算する
        yf ^= M;
        long yd = y.dvl;
        long yc = y.cvl;
        int o = xe - y.epp;
        if (o < 0 || o == 0 && (xd < yd || xd == yd && xc >>> 1 < yc >>> 1)) {  //yの方が絶対値が大きい
          //xとyを入れ換える
          xf = yf;
          xe += o = -o;  //xe=y.epp
          xd = yd;
          xc = yc;
          yf = this.flg;  //後で符号を比較するときに使う
          yd = this.dvl;
          yc = this.cvl;
        }
        //xの方が絶対値が大きいか等しい
        //yを右にずらして小数点の位置を合わせる
        if (0 < o) {
          if (o <= 63) {
            xb = yc << -o;
            yc = yd << -o | yc >>> o;
            yd >>>= o;
          } else if (o == 64) {
            xb = yc;
            yc = yd;
            yd = 0L;
          } else if (o <= 127) {
            xb = yd << -o | yc;
            yc = yd >>> o;
            yd = 0L;
          } else {
            xb = yd | yc;  //絶対値減算を行うとき下位からのボローとして必要
            yc = 0L;
            yd = 0L;
          }
        }
        //絶対値加算または絶対値減算を行う
        if (xf == yf) {  //符号が同じなので絶対値加算を行う
          //yc[1]とyc[0]をsticky bitに押し出す
          xb |= yc << 62;
          //右にずらしてxd[63]を空ける
          xc = xd << 63 | xc >>> 1;
          xd >>>= 1;
          yc = yd << 63 | yc >>> 1;
          yd >>>= 1;
          //下位を右にずらしてxc[63]を空ける
          yc >>>= 1;
          xc >>>= 1;
          //足す
          xc += yc;
          xd += yd + (xc >>> 63);
          //下位を左にずらしてxc[63]を詰める
          xc <<= 1;
          //溢れの処理
          if (xd < 0L) {  //溢れたとき
            xe++;
          } else {  //溢れなかったとき
            xd = xd << 1 | xc >>> 63;  //左にずらしてxd[63]を詰める
            xc <<= 1;
          }
        } else {  //符号が異なるので絶対値減算を行う
          //yc[0]をsticky bitに押し出す
          xb |= yc << 63;
          //下位を右にずらしてxc[63]を空ける
          yc >>>= 1;
          xc >>>= 1;
          //引く
          //  xの方が絶対値が大きいか等しいので負になることはないが0になることがある
          if (xb != 0L) {
            xc--;
          }
          xc -= yc;
          xd -= yd + (xc >>> 63);
          //下位を左にずらしてxc[63]を詰める
          xc <<= 1;
          //正規化する
          if (0L <= xd) {
            if (xd != 0L) {
              xe -= o = Long.numberOfLeadingZeros (xd);
              xd = xd << o | xc >>> -o;
              xc <<= o;
            } else if (xc != 0L) {
              xe -= o = 64 + Long.numberOfLeadingZeros (xc);
              xd = xc << o;
              xc = 0L;
            } else {  //0になった
              xf = epbRoundingMode == EPB_MODE_RM ? M | Z : P | Z;  //RMのとき-0,それ以外は+0
            }
          }
        }  //if 符号が同じなので絶対値加算を行う/符号が異なるので絶対値減算を行う
      }  //if どちらかが±0,±Inf,NaN/両方±0,±Inf,NaN以外
      return this.finish (xf, xe, xd, xc, xb);
    }  //efp.sub(EFP)
    public final EFP sub (EFP x, EFP y) {
      int xf = x.flg;
      int xe = x.epp;
      long xd = x.dvl;
      long xc = x.cvl;
      long xb = 0L;
      int yf = y.flg;
      if ((xf | yf) << 1 != 0) {  //どちらかが±0,±Inf,NaN
        if ((xf | yf) << 3 < 0) {  //どちらかがNaNのときNaN
          this.flg = N;
          return this;
        }
        if ((xf & yf) << 2 < 0 && xf == yf) {  //両方±Infで符号が同じときNaN
          epbFpsr |= EPB_FPSR_OE;
          epbExceptionOperandExponent = yf & M | 0x7fff << 16;
          epbExceptionOperandMantissa = 0x0000000000000000L;
          this.flg = N;
          return this;
        }
        if ((xf & yf) << 1 < 0 && xf == yf) {  //両方±0で符号が同じとき
          this.flg = epbRoundingMode == EPB_MODE_RM ? M | Z : P | Z;  //RMのとき-0,それ以外は+0
          return this;
        }
        if (xf << 1 < 0 || yf << 2 < 0) {  //xが±0またはyが±Infのとき-y
          xf = yf ^ M;
          xe = y.epp;
          xd = y.dvl;
          xc = y.cvl;
        }
        //xが±Infまたはyが±0のときx
      } else {  //両方±0,±Inf,NaN以外
        //減算なのでyの符号を反転して加算する
        yf ^= M;
        long yd = y.dvl;
        long yc = y.cvl;
        int o = xe - y.epp;
        if (o < 0 || o == 0 && (xd < yd || xd == yd && xc >>> 1 < yc >>> 1)) {  //yの方が絶対値が大きい
          //xとyを入れ換える
          xf = yf;
          xe += o = -o;  //xe=y.epp
          xd = yd;
          xc = yc;
          yf = x.flg;  //後で符号を比較するときに使う
          yd = x.dvl;
          yc = x.cvl;
        }
        //xの方が絶対値が大きいか等しい
        //yを右にずらして小数点の位置を合わせる
        if (0 < o) {
          if (o <= 63) {
            xb = yc << -o;
            yc = yd << -o | yc >>> o;
            yd >>>= o;
          } else if (o == 64) {
            xb = yc;
            yc = yd;
            yd = 0L;
          } else if (o <= 127) {
            xb = yd << -o | yc;
            yc = yd >>> o;
            yd = 0L;
          } else {
            xb = yd | yc;  //絶対値減算を行うとき下位からのボローとして必要
            yc = 0L;
            yd = 0L;
          }
        }
        //絶対値加算または絶対値減算を行う
        if (xf == yf) {  //符号が同じなので絶対値加算を行う
          //yc[1]とyc[0]をsticky bitに押し出す
          xb |= yc << 62;
          //右にずらしてxd[63]を空ける
          xc = xd << 63 | xc >>> 1;
          xd >>>= 1;
          yc = yd << 63 | yc >>> 1;
          yd >>>= 1;
          //下位を右にずらしてxc[63]を空ける
          yc >>>= 1;
          xc >>>= 1;
          //足す
          xc += yc;
          xd += yd + (xc >>> 63);
          //下位を左にずらしてxc[63]を詰める
          xc <<= 1;
          //溢れの処理
          if (xd < 0L) {  //溢れたとき
            xe++;
          } else {  //溢れなかったとき
            xd = xd << 1 | xc >>> 63;  //左にずらしてxd[63]を詰める
            xc <<= 1;
          }
        } else {  //符号が異なるので絶対値減算を行う
          //yc[0]をsticky bitに押し出す
          xb |= yc << 63;
          //下位を右にずらしてxc[63]を空ける
          yc >>>= 1;
          xc >>>= 1;
          //引く
          //  xの方が絶対値が大きいか等しいので負になることはないが0になることがある
          if (xb != 0L) {
            xc--;
          }
          xc -= yc;
          xd -= yd + (xc >>> 63);
          //下位を左にずらしてxc[63]を詰める
          xc <<= 1;
          //正規化する
          if (0L <= xd) {
            if (xd != 0L) {
              xe -= o = Long.numberOfLeadingZeros (xd);
              xd = xd << o | xc >>> -o;
              xc <<= o;
            } else if (xc != 0L) {
              xe -= o = 64 + Long.numberOfLeadingZeros (xc);
              xd = xc << o;
              xc = 0L;
            } else {  //0になった
              xf = epbRoundingMode == EPB_MODE_RM ? M | Z : P | Z;  //RMのとき-0,それ以外は+0
            }
          }
        }  //if 符号が同じなので絶対値加算を行う/符号が異なるので絶対値減算を行う
      }  //if どちらかが±0,±Inf,NaN/両方±0,±Inf,NaN以外
      return this.finish (xf, xe, xd, xc, xb);
    }  //efp.sub(EFP,EFP)

    //------------------------------------------------------------------------
    //x = x.tan ()
    //  x=tan(x)
    //y = y.tan (x)
    //  y=tan(x)
    //  正接 tangent タンジェント
    //
    //  グラフ
    //    perl -e "use Math::Trig;use Graph;$g=new Graph();$g->grid();$g->func(sub{tan($_[0])});print$g"
    //    echo read("../misc/efp.gp");graph(tan) | gp -q
    //    +---------+---------+-*-------+---------+---------+--*------+---------+---------+
    //    |                     *                 |            *                          |
    //    |                     *                 |            *                          |
    //    |                    **                 |            *                          |
    //    |                    *                  |            *                          |
    //    +                    *                  +           **                          +
    //    |                    *                  |           *                           |
    //    |                   **                  |           *                           |
    //    |                   *                   |           *                           |
    //    |                   *                   |          **                           |
    //    +                  **                   +          *                            +
    //    |                  *                    |         **                            |
    //    |                 **                    |         *                             |
    //    |                 *                     |        **                             |
    //    |                **                     |       **                              *
    //    +               **                      +      **                              **
    //    |              **                       |     **                              **|
    //    |            ***                        |    **                             *** |
    //    |          ***                          |  ***                            ***   |
    //    |         **                            |***                            ***     |
    //    +-------***---------+---------+--------***--------+---------+---------***-------+
    //    |     ***                            ***|                            **         |
    //    |   ***                            ***  |                          ***          |
    //    | ***                             **    |                        ***            |
    //    |**                              **     |                       **              |
    //    **                              **      +                      **               +
    //    *                              **       |                     **                |
    //    |                             **        |                     *                 |
    //    |                             *         |                    **                 |
    //    |                            **         |                    *                  |
    //    +                            *          +                   **                  +
    //    |                           **          |                   *                   |
    //    |                           *           |                   *                   |
    //    |                           *           |                  **                   |
    //    |                           *           |                  *                    |
    //    +                          **           +                  *                    +
    //    |                          *            |                  *                    |
    //    |                          *            |                 **                    |
    //    |                          *            |                 *                     |
    //    |                          *            |                 *                     |
    //    +---------+---------+------*--+---------+---------+-------*-+---------+---------+
    //
    //  定義域
    //    -inf<=x<=inf
    //
    //  値域
    //    -inf<=tan(x)<=inf
    //
    //  三角関数のとの関係
    //    tan(x)=sin(x)/cos(x)
    //
    //  加法定理
    //    tan(x+y)=(tan(x)+tan(y))/(1-tan(x)*tan(y))
    //
    //  倍角と半角
    //    tan(2*x)=tan(x+x)
    //            =(tan(x)+tan(x))/(1-tan(x)*tan(x))
    //            =2*tan(x)/(1-tan(x)^2)
    //    tan(3*x)=tan(2*x+x)
    //            =(tan(2*x)+tan(x))/(1-tan(2*x)*tan(x))
    //            =(2*tan(x)/(1-tan(x)^2)+tan(x))/(1-2*tan(x)/(1-tan(x)^2)*tan(x))
    //            =(tan(x)^3-3*tan(x))/(3*tan(x)^2-1)
    //    tan(x)=2*tan(x/2)/(1-tan(x/2)^2)
    //    tan(x/2)=(+/-sqrt(tan(x)^2+1)-1)/tan(x)
    //
    //  変数変換1
    //    収束を速くするために|x|<=pi/8にする
    //    tan(pi/4)=1
    //    tan(x+pi/4)=(tan(x)+tan(pi/4))/(1-tan(x)*tan(pi/4))
    //               =(tan(x)+1)/(1-tan(x))
    //    tan(3*pi/4)=-1
    //    tan(x+3*pi/4)=(tan(x)+tan(3*pi/4))/(1-tan(x)*tan(3*pi/4))
    //                 =(tan(x)-1)/(1+tan(x))
    //    tan(x)=(tan(x-pi/4)+1)/(1-tan(x-pi/4))
    //          =-1/tan(x-pi/2)
    //          =(tan(x-3*pi/4)-1)/(1+tan(x-3*pi/4))
    //          =tan(x-pi)
    //                -1/tan(x-pi/2)
    //                  k=3     k=2
    //                  ←      ←
    //                    \  │  /   (tan(x-pi/4)+1)/(1-tan(x-pi/4))
    //                 \  \ │ /  /
    //                   \ \│/ /   ↑k=1
    //           k=0↓~~-- \│/ --~~
    //     tan(x-pi) ────・──── tan(x)
    //                __-- /│\ --__↑k=0
    //           k=1↓   / /│\ \
    //                 /  / │ \  \
    //                    /  │  \
    //                    →      →
    //                    k=2     k=3
    //
    //  変数変換2
    //    場合分けを増やせばチェビシェフ展開の多項式を短くすることができる
    //    tan(pi/8)=(sqrt(tan(pi/4)^2+1)-1)/tan(pi/4)
    //             =(sqrt(1^2+1)-1)/1
    //             =sqrt(2)-1
    //    tan(3*pi/8)=(tan(pi/8)^3-3*tan(pi/8))/(3*tan(pi/8)^2-1)
    //               =((sqrt(2)-1)^3-3*(sqrt(2)-1))/(3*(sqrt(2)-1)^2-1)
    //               =(2-sqrt(2))/(3*sqrt(2)-4)
    //               =(2-sqrt(2))*(3*sqrt(2)+4)/(3*sqrt(2)-4)/(3*sqrt(2)+4)
    //               =(8-6+(6-4)*sqrt(2))/2
    //               =sqrt(2)+1
    //    tan(x)=(tan(x-pi/8)+sqrt(2)-1)/(1-tan(x-pi/8)*(sqrt(2)-1))
    //          =(tan(x-3*pi/8)+sqrt(2)+1)/(1-tan(x-3*pi/8)*(sqrt(2)+1))
    //          =(tan(x-5*pi/8)-(sqrt(2)+1))/(1+tan(x-3*pi/8)*(sqrt(2)+1))
    //          =(tan(x-7*pi/8)-(sqrt(2)-1))/(1+tan(x-3*pi/8)*(sqrt(2)-1))
    //
    //  ローラン級数展開
    //    tan(x)=x-x^3/3+2*x^5/15-17*x^7/315+...
    //          =sum[n=1..inf]{(-1)^n*4^n*(1-4^n)*B(2*n)*x^(2*n-1)/(2*n)!}  |x|<pi/2
    //    f(n,x)=sum(k=1,n,(-1)^k*4^k*(1-4^k)*bernreal(2*k)*x^(2*k-1)/(2*k)!)
    //
    //  チェビシェフ展開
    //    echo read("../misc/efp.gp");eval("f(x)=tan(x)");a=-Pi/8;b=Pi/8;forstep(n=1,35,2,printf("%4d",floor(closeness(f,chebyshev(f,a,b,n),a,b,10000)))) | gp -q
    //    echo read("../misc/efp.gp");eval("f(x)=tan(x)");a=-Pi/16;b=Pi/16;forstep(n=1,35,2,printf("%4d",floor(closeness(f,chebyshev(f,a,b,n),a,b,10000)))) | gp -q
    //    echo read("../misc/efp.gp");eval("f(x)=tan(x)");a=-Pi/32;b=Pi/32;forstep(n=1,35,2,printf("%4d",floor(closeness(f,chebyshev(f,a,b,n),a,b,10000)))) | gp -q
    //    echo read("../misc/efp.gp");eval("f(x)=tan(x)");a=-Pi/64;b=Pi/64;forstep(n=1,21,2,printf("%4d",floor(closeness(f,chebyshev(f,a,b,n),a,b,10000)))) | gp -q
    //    echo read("../misc/efp.gp");eval("f(x)=tan(x)");a=-Pi/128;b=Pi/128;forstep(n=1,21,2,printf("%4d",floor(closeness(f,chebyshev(f,a,b,n),a,b,10000)))) | gp -q
    //    echo read("../misc/efp.gp");eval("f(x)=tan(x)");a=-Pi/256;b=Pi/256;forstep(n=1,15,2,printf("%4d",floor(closeness(f,chebyshev(f,a,b,n),a,b,10000)))) | gp -q
    //       1   3   5   7   9  11  13  15  17  19  21  23  25  27  29  31  33  35
    //       4   9  15  20  26  32  38  43  49  55  61  67  72  78  84  90  96 102  |x|<=pi/8
    //       6  13  21  29  36  44  52  60  67  75  83  91  99 107 115 123 130 138  |x|<=pi/16  pi/8  4要素
    //       8  17  27  37  46  56  66  76  86  95 105 115 125 135 145 155 165 175  |x|<=pi/32  pi/16  8要素
    //      10  21  33  45  56  68  80  92 104 115 127  |x|<=pi/64  pi/32  16要素
    //      12  25  39  53  66  80  94 108 122 135 149  |x|<=pi/128  pi/64  32要素
    //      14  29  45  61  76  92 108 124  |x|<=pi/256  pi/128  64要素
    //
    public final EFP tan () {
      return this.tan (this);
    }  //efp.tan()
    public final EFP tan (EFP x) {
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        if (xf << 1 < 0) {  //±0
          this.flg = xf;  //tan(±0)=±0
        } else if (xf << 2 < 0) {  //±Inf
          epbFpsr |= EPB_FPSR_OE;
          epbExceptionOperandExponent = xf & M | 0x7fff << 16;
          epbExceptionOperandMantissa = 0x0000000000000000L;
          this.flg = N;  //tan(±Inf)=NaN
        } else {  //NaN
          this.flg = N;  //tan(NaN)=NaN
        }
        return this;
      }
      //±0,±Inf,NaN以外
      if (false) {  //sin/cos。[90] 800ns
        EFP c = new EFP ().inner ().cos (x);  //cos(x)
        return this.sin (x).outer ().div (c);  //sin(x)/cos(x)
      } else if (false) {  //4分割。[90] 600ns
        this.inner ();
        EFP s = new EFP ();
        EFP t = new EFP ();
        EFP u = new EFP ().iabs (x);  //|x|
        EFP u2 = new EFP ();
        int k = 0;  //|x|+pi/8の8分象限
        //if (u.gt (PI_8)) {  //|x|>pi/8
        if (u.epp >= -1 || (u.epp == -2 && u.dvl >= 0xc90fdaa22168c234L)) {  //|x|>=pi/8。下位の比較は省略する
          //s.iadd (u, PI_8).quo (PI_4);  //|x|+pi/8をpi/4で割った商
          s.iadd (u, PI_8).imul (FOUR_PI).trunc ();  //|x|+pi/8をpi/4で割った商
          //  |x|をpi/4で割った余りを求めるとき|x|がpi/4の整数倍に近いと桁落ちが発生するので倍精度で計算する
          u.sub (t.imulw (u2, s, PI_4)).sub (u2).sub (t.imul (s, PI_4A));  //|x|をpi/4で割った余り。[-pi/8,pi/8]
          k = s.geti () & 3;  //|x|+pi/8の8分象限
        }
        u2.isqu (u);  //u^2
        this.imul (TAN_C33, u2)
          .iadd (TAN_C31).imul (u2)
            .iadd (TAN_C29).imul (u2)
              .iadd (TAN_C27).imul (u2)
                .iadd (TAN_C25).imul (u2)
                  .iadd (TAN_C23).imul (u2)
                    .iadd (TAN_C21).imul (u2)
                      .iadd (TAN_C19).imul (u2)
                        .iadd (TAN_C17).imul (u2)
                          .iadd (TAN_C15).imul (u2)
                            .iadd (TAN_C13).imul (u2)
                              .iadd (TAN_C11).imul (u2)
                                .iadd (TAN_C9).imul (u2)
                                  .iadd (TAN_C7).imul (u2)
                                    .iadd (TAN_C5).imul (u2)
                                      .iadd (TAN_C3).imul (u2)
                                        .iadd (TAN_C1).imul (u);
        if (k == 1) {
          t.negdec (this);  //1-tan(x-pi/4)
          this.inc ().div (t);  //(1+tan(x-pi/4))/(1-tan(x-pi/4))
        } else if (k == 2) {
          this.rcp ().ineg ();  //-1/tan(x-pi/2)
        } else if (k == 3) {
          t.inc (this);  //tan(x-3*pi/4)+1
          this.dec ().div (t);  //(tan(x-3*pi/4)-1)/(tan(x-3*pi/4)+1)
        }
        return this.outer ().neg (xf < 0);  //tanは奇関数なのでxの符号を掛ける
      } else {  //128分割。[90] 350ns
        if (x.epp >= 16) {  //|x|が大きすぎる
          EFP c = new EFP ().inner ().cos (x);  //cos(x)
          return this.sin (x).outer ().div (c);  //sin(x)/cos(x)
        }
        int savedFpsr = epbFpsr;
        this.inner ();
        if (this == x) {
          x = new EFP (x);
        }
        if (x.epp < -3) {  //|x|<1/8
          EFP x2 = new EFP ().isqu (x);  //x^2
          this.imul (TAN8_C21, x2)
            .iadd (TAN8_C19).imul (x2)
              .iadd (TAN8_C17).imul (x2)
                .iadd (TAN8_C15).imul (x2)
                  .iadd (TAN8_C13).imul (x2)
                    .iadd (TAN8_C11).imul (x2)
                      .iadd (TAN8_C9).imul (x2)
                        .iadd (TAN8_C7).imul (x2)
                          .iadd (TAN8_C5).imul (x2)
                            .iadd (TAN8_C3).imul (x2)
                              .iadd (TAN8_C1).outer ().mul (x);
          return this.originLowerUpper (x).correctUnderflow (savedFpsr);
        }
        EFP s = new EFP ();
        EFP t = new EFP ();
        EFP u = new EFP ().iabs (x);  //|x|
        EFP u2 = new EFP ();
        s.iadd (u, TAN7_X).imul (TAN7_Y).trunc ();  //|x|+pi/256をpi/128で割った商
        //  |x|をpi/128で割った余りを求めるとき|x|がpi/128の整数倍に近いと桁落ちが発生するので倍精度で計算する
        u.sub (t.imulw (u2, s, TAN7_Z)).sub (u2).sub (t.imul (s, TAN7_ZA));  //|x|をpi/128で割った余り。[-pi/256,pi/256]
        int k = s.geti () & 127;  //|x|+pi/256をpi/128で割った商の下位7bit
        u2.isqu (u);  //u^2
        this.imul (TAN7_C11, u2)
          .iadd (TAN7_C9).imul (u2)
            .iadd (TAN7_C7).imul (u2)
              .iadd (TAN7_C5).imul (u2)
                .iadd (TAN7_C3).imul (u2)
                  .iadd (TAN7_C1).imul (u);
        if (k != 0) {
          if (k <= 63) {
            t = TAN7_T[k];
            s.imul (this, t).negdec ();
            this.iadd (t).div (s);  //(tan(x-k*pi/128)+t)/(1-tan(k*pi/128)*t)
          } else if (k == 64) {
            this.rcp ().ineg ();  //-1/tan(x-pi/2)
          } else {
            t = TAN7_T[128 - k];
            s.imul (this, t).inc ();
            this.sub (t).div (s);  //(tan(x-(128-k)*pi/128)-t)/(1+tan((128-k)*pi/128)*t)
          }
        }
        return this.outer ().neg (xf < 0);  //tanは奇関数なのでxの符号を掛ける
      }
    }  //efp.tan(EFP)

    //------------------------------------------------------------------------
    //x = x.tanh ()
    //  x=tanh(x)
    //y = y.tanh (x)
    //  y=tanh(x)
    //  双曲線正接 hyperbolic tangent ハイパボリックタンジェント
    //
    //  グラフ
    //    perl -e "use Math::Trig;use Graph;$g=new Graph();$g->grid();$g->func(sub{tanh($_[0])});print$g"
    //    echo read("../misc/efp.gp");graph(tanh) | gp -q
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +              **************************
    //    |                                       |        *******                        |
    //    |                                       |    *****                              |
    //    |                                       |  ***                                  |
    //    |                                       |***                                    |
    //    +---------+---------+---------+--------***--------+---------+---------+---------+
    //    |                                    ***|                                       |
    //    |                                  ***  |                                       |
    //    |                              *****    |                                       |
    //    |                        *******        |                                       |
    //    **************************              +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //
    //  定義域
    //    -inf<=x<=inf
    //
    //  値域
    //    -1<=tanh(x)<=1
    //
    //  双曲線関数との関係
    //    tanh(x)=sinh(x)/cosh(x)
    //
    //  指数関数との関係
    //    tanh(x)=(e^x-e^(-x))/(e^x+e^(-x))
    //           =(e^(2*x)-1)/(e^(2*x)+1)
    //    1-tanh(x)=2*e^-x/(e^x+e^-x)
    //
    //  微分
    //    df{tanh(x)}=1-tanh(x)^2
    //               =sech(x)^2
    //               =1/cosh(x)^2
    //
    //  加法定理
    //    tanh(x+y)=(tanh(x)+tanh(y))/(1+tanh(x)*tanh(y))
    //
    //  定義域の制限
    //    仮数部がLENbitのとき|x|<=atanh(1-2^-LEN)でなければtanh(x)とsgn(x)を区別できない
    //    92bitならば
    //    > atanh(1-2^-92);
    //    32.231343896037456887901293647754723317576611492206
    //
    //  変数変換1
    //    tanh(x+log((c+1)/(c-1))/2)=tanh(x+log((1+1/c)/(1-1/c))/2)
    //                              =tanh(x+atanh(1/c))
    //                              =(tanh(x)+tanh(atanh(1/c)))/(1+tanh(x)*tanh(atanh(1/c)))
    //                              =(tanh(x)+1/c)/(1+tanh(x)*1/c)
    //                              =(c*tanh(x)+1)/(c+tanh(x))
    //                              =(c^2+c*tanh(x)-c^2+1)/(c+tanh(x))
    //                              =c-(c^2-1)/(c+tanh(x))
    //    tanh(x+1*log((c+1)/(c-1))/2)=(c*tanh(x)+1)/(c+tanh(x))
    //    tanh(x+2*log((c+1)/(c-1))/2)=(c^2*tanh(x)+2*c+tanh(x))/(c^2+2*c*tanh(x)+1)
    //    tanh(x+3*log((c+1)/(c-1))/2)=(c^3*tanh(x)+3*c^2+3*c*tanh(x)+1)/(c^3+3*c^2*tanh(x)+3*c+tanh(x))
    //    tanh(x+4*log((c+1)/(c-1))/2)=(c^4*tanh(x)+4*c^3+6*c^2*tanh(x)+4*c+tanh(x))/(c^4+4*c^3*tanh(x)+6*c^2+4*c*tanh(x)+1)
    //    tanh(x+5*log((c+1)/(c-1))/2)=(c^5*tanh(x)+5*c^4+10*c^3*tanh(x)+10*c^2+5*c*tanh(x)+1)/(c^5+5*c^4*tanh(x)+10*c^3+10*c^2*tanh(x)+5*c+tanh(x))
    //    tanh(x+k*log((c+1)/(c-1))/2)は(c+1)^kを二項展開してkと奇偶が同じ項にtanh(x)を掛けたものをkと奇偶が異なる項にtanh(x)を掛けたもので割ったものになっている
    //    cが定数でkが大きすぎなければすべてのkについてc0+1/(c1+c2*tanh(x))の形に整理して係数をテーブルに列挙しておくことができる
    //    log((c+1)/(c-1))/2が2の累乗になるようにcを定めれば分割に除算はいらない
    //    例えば、|x|<=1/4の範囲をチェビシェフ展開する場合、幅が1/2なので
    //      log((c+1)/(c-1))/2=1/2
    //      log((c+1)/(c-1))=1
    //      (c+1)/(c-1)=e
    //      c=(e+1)/(e-1)
    //    を使ってテーブルを作ればよい
    //    しかし、チェビシェフ展開の項数を減らそうとして幅を狭くするとテーブルが巨大化してしまう
    //    実用的な範囲ではtanh(x)=(e^(2*x)-1)/(e^(2*x)+1)より速くならないかも知れない
    //
    //  変数変換2
    //    tanh(x+k*log((c+1)/(c-1))/2)でk=2^jの式だけテーブルに展開しておいて平行移動の式を動的に作る
    //    分子と分母を分けておけば除算は最後の1回だけで済む
    //
    //  変数変換3
    //    xの指数部を見て開始範囲を選択する
    //    テーブルを参照してxが範囲の中央の1/3に含まれているか確認する
    //    中央の1/3に含まれていない場合は中央の1/3まで平行移動するための式を分子と分母に分けて作る
    //    xが十分に小さくなるまで繰り返す
    //    チェビシェフ展開で計算する
    //    平行移動の式で元の位置に戻す。最後に1回だけ除算が必要になる
    //
    //  ローラン級数展開
    //    tanh(x)=x+x^3/3+2*x^5/15+17*x^7/315+...
    //           =sum[n=1..inf]{4^n*(4^n-1)*B(2*n)*x^(2*n-1)/(2*n)!}  |x|<pi/2
    //    f(n,x)=sum(k=1,n,4^k*(4^k-1)*bernreal(2*k)*x^(2*k-1)/(2*k)!)
    //    echo for(k=1,10,x=eval("4^k*(4^k-1)*bernfrac(2*k)/(2*k)!");print("    //    ",x,"*x^",2*k-1)) | gp -q
    //    1*x^1
    //    -1/3*x^3
    //    2/15*x^5
    //    -17/315*x^7
    //    62/2835*x^9
    //    -1382/155925*x^11
    //    21844/6081075*x^13
    //    -929569/638512875*x^15
    //    6404582/10854718875*x^17
    //    -443861162/1856156927625*x^19
    //
    //  チェビシェフ展開
    //    0の近くだけチェビシェフ展開を使う
    //    echo read("../misc/efp.gp");eval("f(x)=tanh(x)");a=-0.25;b=0.25;forstep(n=1,31,2,printf("%4d",floor(closeness(f,chebyshev(f,a,b,n),a,b,10000)))) | gp -q
    //    echo read("../misc/efp.gp");eval("f(x)=tanh(x)");a=-0.125;b=0.125;forstep(n=1,31,2,printf("%4d",floor(closeness(f,chebyshev(f,a,b,n),a,b,10000)))) | gp -q
    //    echo read("../misc/efp.gp");eval("f(x)=tanh(x)");a=-0.0625;b=0.0625;forstep(n=1,31,2,printf("%4d",floor(closeness(f,chebyshev(f,a,b,n),a,b,10000)))) | gp -q
    //       1   3   5   7   9  11  13  15  17  19  21  23  25  27  29  31
    //       6  12  19  26  33  40  47  54  61  69  76  83  90  97 105 112
    //       8  16  25  34  43  52  61  70  79  88  98 107 116 125 134 144
    //      10  20  31  42  53  64  75  86  97 108 120 131 142 153 164 176
    //
    public final EFP tanh () {
      return this.tanh (this);
    }  //efp.tanh()
    public final EFP tanh (EFP x) {
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        if (xf << 2 < 0) {  //tanh(±Inf)=±1
          this.flg = xf & M;
          this.epp = 0;
          this.dvl = MSB;
          this.cvl = 0L;
        } else {  //tanh(±0)=±0, tanh(NaN)=NaN
          this.flg = xf;
        }
        return this;
      }
      //±0,±Inf,NaN以外
      //  e^xを経由する方法はオーバーフローを発生させずに計算できる範囲が狭いので|x|が大きい場合を分ける必要がある
      int xe = x.epp;
      if (xe < -2) {  //|x|<0.25
        int savedFpsr = epbFpsr;
        this.inner ();
        if (this == x) {
          x = new EFP (x);
        }
        EFP x2 = new EFP ().isqu (x);  //x^2
        this.imul (TANH_C27, x2)
          .iadd (TANH_C25).imul (x2)
            .iadd (TANH_C23).imul (x2)
              .iadd (TANH_C21).imul (x2)
                .iadd (TANH_C19).imul (x2)
                  .iadd (TANH_C17).imul (x2)
                    .iadd (TANH_C15).imul (x2)
                      .iadd (TANH_C13).imul (x2)
                        .iadd (TANH_C11).imul (x2)
                          .iadd (TANH_C9).imul (x2)
                            .iadd (TANH_C7).imul (x2)
                              .iadd (TANH_C5).imul (x2)
                                .iadd (TANH_C3).imul (x2)
                                  .iadd (TANH_C1).outer ().mul (x);
        return this.originUpperLower (x).correctUnderflow (savedFpsr);
      }
      //0.25<=|x|
      if (false) {
        EFP c = new EFP ().inner ().cosh (x);  //cosh(x)
        return this.sinh (x).outer ().div (c);  //sinh(x)/cosh(x) [90]
      } else if (6 <= xe) {  //2^6<=|x|
        //  x=2^6のとき
        //  1-tanh(x)=1-(e^x-e^(-x))/(e^x+e^(-x))
        //           =2*e^(-x)/(e^x+e^(-x))
        //  の値は
        //  echo x=eval("2^6");log(2*exp(-x)/(exp(x)+exp(-x)))/log(2) | gp -q
        //  -183.66496523378731614207035916824219359
        //  であるから2^6<=xのときtanh(x)と1を区別できない
        //  tanh(x)は奇関数なのでx<=-2^6の場合も同様にtanh(x)と-1を区別できない
        epbFpsr |= EPB_FPSR_X2;  //不正確な結果
        this.flg = xf & M;  //±1
        this.epp = 0;
        this.dvl = MSB;
        this.cvl = 0L;
        if (xf < 0) {
          if (epbRoundingMode == EPB_MODE_RZ || epbRoundingMode == EPB_MODE_RP) {
            this.nextup (epbRoundingPrec);
          }
        } else {
          if (epbRoundingMode == EPB_MODE_RZ || epbRoundingMode == EPB_MODE_RM) {
            this.nextdown (epbRoundingPrec);
          }
        }
        return this;
      } else {
        EFP t = new EFP ().inner ().imul2 (x).exp ();  //e^(2*x)
        this.dec (t);
        t.inc ();
        return this.outer ().div (t);  //(e^(2*x)-1)/(e^(2*x)+1) [90]
      }
    }  //efp.tanh(EFP)

    //------------------------------------------------------------------------
    //x = x.tgamma ()
    //  x=Γ(x)
    //y = y.tgamma (x)
    //  y=Γ(x)
    //  ガンマ関数
    //
    //  グラフ
    //    echo read("../misc/efp.gp");graph(gamma) | gp -q
    //    *---------*---------+**----**-+---------+-*-------+---------+---------+-----**--+
    //    *         *           *    *            | *                                 *   |
    //    *         *           *    *            | **                               **   |
    //    *         *           *    *            |  *                               *    |
    //    *        **           *    *            |  *                              **    |
    //    *        *            *   **            +  *                              *     +
    //    *        *            **  *             |  *                             **     |
    //    *        *             *  *             |  **                           **      |
    //    *        *             ****             |   *                          **       |
    //    *        *                              |   *                          *        |
    //    *        *                              +   **                       ***        +
    //    *        *                              |    *                      **          |
    //    *        *                              |    **                    **           |
    //    *        *                              |     **                 ***            |
    //    *        *                              |      ***            ****              |
    //    **      **                              +        *****  *******                 +
    //    |*      *                               |            ****                       |
    //    |*     **                               |                                       |
    //    |**   **                                |                                       |
    //    | *****                                 |                                       |
    //    +---------+---------+---------+---------+---------+---------+---------+---------+
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |            **                         |                                       |
    //    +           *****                       +                                       +
    //    |           *   **                      |                                       |
    //    |          **    *                      |                                       |
    //    |          *     *                      |                                       |
    //    |          *     **                     |                                       |
    //    +          *      *                     +                                       +
    //    |          *      *                     |                                       |
    //    |          *      *                     |                                       |
    //    |          *      *                     |                                       |
    //    |          *      *                     |                                       |
    //    +          *      **                    +                                       +
    //    |          *       *                    |                                       |
    //    |          *       *                    |                                       |
    //    |         **       *              ***   |                                       |
    //    |         *        *              * *   |                                       |
    //    +---------*--------*+---------+--**-**--+---------+---------+---------+---------+
    //
    //  Γ(x)=int[t=0..∞]{e^-t*t^(x-1)*dt}
    //  Γ(n)=(n-1)!
    //  Γ(n+1)=n!
    //        =n*Γ(n)
    //
    //  x<0のとき
    //    Γ(x)*Γ(1-x)=π/sin(π*x)
    //    で1<xにする
    //    Γ(x)=π/sin(π*x)/Γ(1-x)
    //        =π/sin(π*x)/e^lgamma(1-x)
    //
    //  x==-0のとき
    //    -∞
    //
    //  x==+0のとき
    //    +∞
    //
    //  0<xのとき
    //    Γ(x)=e^lgamma(x)
    //
    public final EFP tgamma () {
      return this.tgamma (this);
    }  //efp.tgamma()
    public final EFP tgamma (EFP x) {
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        this.flg = (xf == (P | Z) || xf == (P | I) ? P | I :  //tgamma(+0)=tgamma(+Inf)=+Inf
                    xf == (M | Z) ? M | I :  //tgamma(-0)=-Inf
                    N);  //tgamma(NaN)=tgamma(-Inf)=NaN
        return this;
      }
      //±0,±Inf,NaN以外
      this.inner ();
      if (xf < 0) {  //x<0
        EFP t = new EFP ().mul (PI, x).sin ();  //sin(π*x)
        this.negdec (x).lgamma ().exp ().mul (t).rcpdiv (PI);  //π/(e^lgamma(1-x)*sin(π*x))
      } else {  //0<x
        this.lgamma (x).exp ();  //e^lgamma(x)
      }
      return this.outer ().finish ();
    }  //efp.tgamma(EFP)

    //------------------------------------------------------------------------
    //s = x.toString ()
    //  10進数文字列化
    //
    //  絶対値が1以上で整数部が有効bit数を表現するのに十分な桁数に収まるとき
    //    指数部を付けずに出力する
    //    小数部の末尾の0を省略する
    //    小数部がすべて省略されたときは小数点も省略する
    //  絶対値が1未満で整数部の0と小数部を合わせて有効bit数を表現するのに十分な桁数+3桁に収まるとき
    //    指数部を付けずに出力する
    //    小数部の末尾の0を省略する
    //  それ以外
    //    整数部が1~9の浮動小数点形式で出力する
    //
    @Override public String toString () {
      int xf = this.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        return (xf == (P | Z) ? "0" :
                xf == (M | Z) ? "-0" :
                xf == (P | I) ? "Infinity" :
                xf == (M | I) ? "-Infinity" :
                xf << 3 < 0 ? "NaN" : "???");
      }
      //±0,±Inf,NaN以外
      this.inner ();
      EFP x = new EFP ().iabs (this);  //絶対値
      //10進数で表現したときの指数部を求める
      //  10^e<=x<10^(e+1)となるeを求める
      int e = (int) Math.floor ((double) x.epp * 0.30102999566398119521373889472);  //log10(2)
      //10^-eを掛けて1<=x<10にする
      //  非正規化数の最小値から正規化数の最大値まで処理できなければならない
      //  10^-eを計算してからまとめて掛ける方法は10^-eがオーバーフローするおそれがあるので不可
      if (0 < e) {  //10<=x
        x.imul (EFP_TEN_M16QR[e & 15]);
        if (16 <= e) {
          x.imul (EFP_TEN_M16QR[16 + (e >> 4 & 15)]);
          if (256 <= e) {
            x.imul (EFP_TEN_M16QR[32 + (e >> 8 & 15)]);
            if (4096 <= e) {
              x.imul (EFP_TEN_M16QR[48 + (e >> 12)]);
            }
          }
        }
      } else if (e < 0) {  //x<1
        x.imul (EFP_TEN_P16QR[-e & 15]);
        if (e <= -16) {
          x.imul (EFP_TEN_P16QR[16 + (-e >> 4 & 15)]);
          if (e <= -256) {
            x.imul (EFP_TEN_P16QR[32 + (-e >> 8 & 15)]);
            if (e <= -4096) {
              x.imul (EFP_TEN_P16QR[48 + (-e >> 12)]);
            }
          }
        }
      }
      this.outer ();
      //整数部2桁、小数部EFP_DECIMAL_PREC+4&-4桁の10進数に変換する
      //  1<=x<10なのでw[1]が先頭になるはずだが誤差で前後にずれる可能性がある
      //  小数部を10000倍して整数部を引くことを繰り返すため、桁数に余裕のない浮動小数点数のまま行うと情報落ちが発生して誤差が蓄積する
      //  固定小数点に切り替えて誤差なしで計算する
      int[] w = new int[2 + (EFP_DECIMAL_PREC + 4 & -4)];
      {
        int t = 31 - x.epp;
        long x1 = x.dvl >>> t;  //上位32bitが整数部、下位32bitが小数部
        long x2 = x.dvl << -t | x.cvl >>> t;  //tは誤差を考慮しても最大32、x.cvlは下位32bitが0なのではみ出さない
        long x3 = x2 & 0xffffffffL;
        x2 >>>= 32;
        t = XEiJ.FMT_BCD4[(int) (x1 >>> 32)];  //整数部
        w[0] = t >>  4;
        w[1] = t       & 15;
        for (int i = 2; i < 2 + (EFP_DECIMAL_PREC + 4 & -4); i += 4) {
          x3 *= 10000L;
          x2 = x2 * 10000L + (x3 >>> 32);
          x3 &= 0xffffffffL;
          x1 = (x1 & 0xffffffffL) * 10000L + (x2 >>> 32);
          x2 &= 0xffffffffL;
          t = XEiJ.FMT_BCD4[(int) (x1 >>> 32)];  //整数部
          w[i    ] = t >> 12;
          w[i + 1] = t >>  8 & 15;
          w[i + 2] = t >>  4 & 15;
          w[i + 3] = t       & 15;
        }
      }
      //先頭の位置を確認する
      //  w[h]が先頭(0でない最初の数字)の位置
      int h = w[0] != 0 ? 0 : w[1] != 0 ? 1 : 2;
      //EFP_DECIMAL_PREC+1桁目を四捨五入する
      int o = h + EFP_DECIMAL_PREC;  //w[o]は四捨五入する桁の位置。w[]の範囲内
      if (5 <= w[o]) {
        int i = o;
        while (10 <= ++w[--i]) {
          w[i] = 0;
        }
        if (i < h) {  //先頭から繰り上がった。このとき新しい先頭は1でそれ以外はすべて0
          h--;  //先頭を左にずらす
          o--;  //末尾を左にずらす
        }
      }
      //先頭の位置に応じて指数部を更新する
      //  w[h]が整数部、w[h+1..o-1]が小数部。10^eの小数点はw[h]の右側。整数部の桁数はe+1桁
      e -= h - 1;
      //末尾の位置を確認する
      //  w[o-1]が末尾(0でない最後の数字)の位置
      while (w[o - 1] == 0) {  //全体は0ではないので必ず止まる。小数点よりも左側で止まる場合があることに注意
        o--;
      }
      //文字列に変換する
      StringBuilder sb = new StringBuilder ();
      //符号を付ける
      if (xf < 0) {
        sb.append ('-');
      }
      //指数形式にするかどうか選択する
      if (0 <= e && e < EFP_DECIMAL_PREC) {  //1<=x<10^EFP_DECIMAL_PREC。指数形式にしない
        do {
          sb.append ((char) ('0' + w[h++]));  //整数部。末尾の位置に関係なく1の位まで書く
        } while (0 <= --e);
        if (h < o) {  //小数部がある
          sb.append ('.');  //小数部があるときだけ小数点を書く
          do {
            sb.append ((char) ('0' + w[h++]));  //小数部
          } while (h < o);
        }
      } else if (-4 <= e && e < 0) {  //10^-4<=x<1。指数形式にしない
        sb.append ('0');  //整数部の0
        sb.append ('.');  //小数点
        while (++e < 0) {
          sb.append ('0');  //小数部の先頭の0の並び
        }
        do {
          sb.append ((char) ('0' + w[h++]));  //小数部
        } while (h < o);
      } else {  //x<10^-4または10^EFP_DECIMAL_PREC<=x。指数形式にする
        sb.append ((char) ('0' + w[h++]));  //整数部
        if (h < o) {  //小数部がある
          sb.append ('.');  //小数部があるときだけ小数点を書く
          do {
            sb.append ((char) ('0' + w[h++]));  //小数部
          } while (h < o);
        }
        sb.append ('e');  //指数部の始まり
        if (false) {
          sb.append (e);
        } else {
          if (e < 0) {
            sb.append ('-');  //指数部の負符号
            e = -e;
          } else {
            sb.append ('+');  //指数部の正符号
          }
          e = XEiJ.fmtBcd8 (e);
          int t = Integer.numberOfLeadingZeros (e);
          if (t <= 27) {
            if (t <= 23) {
              if (t <= 19) {
                if (t <= 15) {
                  sb.append ((char) ('0' + (e >>> 16 & 15)));
                }
                sb.append ((char) ('0' + (e >>> 12 & 15)));
              }
              sb.append ((char) ('0' + (e >>>  8 & 15)));
            }
            sb.append ((char) ('0' + (e >>>  4 & 15)));
          }
          sb.append ((char) ('0' + (e        & 15)));
        }
      }
      return sb.toString ();
    }  //efp.toString()

    //------------------------------------------------------------------------
    //x = x.trunc ()
    //  x=trunc(x)
    //y = y.trunc (x)
    //  y=trunc(x)
    //  切り落とし truncate
    //
    //  グラフ
    //    perl -e "use Graph;$g=new Graph();$g->grid();$g->func(sub{int($_[0])});print$g"
    //    echo read("../misc/efp.gp");graph(truncate) | gp -q
    //    +---------+---------+---------+---------+---------+---------+---------+---------*
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                             ***********
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +                   ***********         +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                                       +         ***********                   +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +---------+---------+---------*********************---------+---------+---------+
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +                   ***********         +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    +         ***********                   +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    ***********                             +                                       +
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    |                                       |                                       |
    //    *---------+---------+---------+---------+---------+---------+---------+---------+
    //
    //    ±0,±Inf,NaN    そのまま
    //    e<=-1          すべて小数部なので±0
    //    0<=e&&e<LEN-1  整数部と小数部が両方あるので小数部を消す
    //    LEN-1<=e       すべて整数部なのでそのまま
    //
    public final EFP trunc () {
      return trunc (this);
    }  //efp.trunc()
    public final EFP trunc (EFP x) {  //1.6ns
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        this.flg = xf;
        return this;
      }
      //±0,±Inf,NaN以外
      int xe = x.epp;
      if (xe < 0) {  //すべて小数部
        epbFpsr |= EPB_FPSR_X2;  //不正確な結果
        this.flg = xf | Z;  //±0
        return this;
      }
      long xd = x.dvl;
      long xc = x.cvl;
      if (xe <= 63) {  //0..63。dの途中または末尾まで整数部
        long m = MSB >> xe;  //整数部のマスク。符号に注意
        if ((xd & ~m | xc) != 0L) {  //小数部が0ではない
          epbFpsr |= EPB_FPSR_X2;  //不正確な結果
          xd &= m;  //小数部を切り捨てる
          xc = 0L;
        }
      } else if (xe <= LEN - 2) {  //64..90。cの途中まで整数部
        long m = MSB >> xe;  //整数部のマスク。符号に注意
        if ((xc & ~m) != 0L) {  //小数部が0ではない
          epbFpsr |= EPB_FPSR_X2;  //不正確な結果
          xc &= m;  //小数部を切り捨てる
        }
      }
      //すべて整数部のときはそのまま
      return this.finish (xf, xe, xd, xc, 0L);
    }  //efp.trunc(EFP)

    //------------------------------------------------------------------------
    //x = x.ulp ()
    //  x=ulp(x)
    //y = y.ulp (x)
    //  y=ulp(x)
    //  ulp
    //
    //  最下位bitの単位(ulp;unit last place)
    //  nextup(abs(x))-abs(x)
    //  ulp(±0)=指数部が最小の値, ulp(±Inf)=±Inf, ulp(NaN)=NaN
    //
    public final EFP ulp () {
      return this.ulp (this);
    };  //efp.ulp()
    public final EFP ulp (EFP x) {
      int xf = x.flg;
      if (xf << 1 != 0) {  //±0,±Inf,NaN
        if (xf << 1 < 0) {  //±0
          this.flg = P;
          this.epp = -32768;
          this.dvl = MSB;
          this.cvl = 0L;
        } else {
          this.flg = xf & ~M;
        }
        return this;
      }
      //±0,±Inf,NaN以外
      this.flg = P;
      this.epp = x.epp - (LEN - 1);
      this.dvl = MSB;
      this.cvl = 0L;
      return this;
    };  //efp.ulp(EFP)

  }  //class EFP



  //------------------------------------------------------------------------
  //コプロセッサインタフェイス
  //
  //  CIR(コプロセッサインタフェイスレジスタ)を介して浮動小数点命令を対話形式で実行する
  //  on-chip FPUとやることは同じだが、命令の中断、保存、復元、再開ができる
  //  浮動小数点命令をコマンドワードで分類するところまではon-chip FPUと同じ
  //  そこからさらに命令の処理段階で分類する
  //
  //  CPU空間(FC=7)
  //    0x...0....  Breakpoint Acknowledge
  //    0x...1....  Access Level Control
  //    0x...2....  Coprocessor Communications
  //    0x00020000  id=0
  //    0x00022000  id=1  MC68881/MC68882
  //    0x00024000  id=2
  //    0x00026000  id=3
  //    0x00028000  id=4
  //    0x0002a000  id=5
  //    0x0002c000  id=6
  //    0x0002e000  id=7
  //    0x...f....  Interrupt Acknowledge
  //
  //  拡張ボード
  //    0x00e9e000  JP1  数値演算プロセッサボード(CZ-6BP1/CZ-6BP1A)
  //    0x00e9e080  JP2  数値演算プロセッサボード(CZ-6BP1/CZ-6BP1A)
  //
  //  FSAVE
  //    $04 save CIRから1ワードのフォーマットワードを読み出す
  //    $01xxが返ったときはカムアゲインなので読み直す
  //    MC68882のフォーマットワードは$00xx、$1F38、$1FD4のいずれか
  //      $00xxはヌルステート。xxは無効。ヌルステートフレームのサイズは0バイト
  //      $1F38はアイドルステート。アイドルステートフレームのサイズは$38=56バイト
  //      $1FD4はビジーステート。ビジーステートフレームのサイズは$D4=212バイト
  //    ヌルステートのときはここで終わり
  //    $10 operand CIRからステートフレームを読み出す
  //    FSAVEはプレデクリメントが前提なのでロング単位で逆順に読み出される
  //    スタックにステートフレームをプッシュする
  //    スタックにフォーマットワード<<16をプッシュする
  //  FRESTORE
  //    スタックからフォーマットワード<<16をポップする
  //    $06 restore CIRにフォーマットワードを書き込む
  //    $06 restore CIRからフォーマットワードを読み出す
  //    書き込んだフォーマットワードがそのまま返ればよい。$02xxが返ったときは不正なフォーマットワードなのでここで失敗
  //    スタックからステートフレームをポップする
  //    $10 operand CIRにステートフレームを書き込む
  //    FRESTOREはポストインクリメントが前提なのでロング単位で正順に書き込む
  //    異常なステートフレームをリストアすると、マニュアルにないレスポンスが返ったり、オペランドCIRのアクセスがプロトコル違反ではなくてバスエラーになったり、かなりおかしなことになる
  //    $06 restore CIRにヌルステートの$0000を書き込むとリセットされる
  //    fp0-fp7はすべてNon-signaling NaNになり、FPCRとFPSRはゼロクリアされる
  //    --------------------------------
  //    > cir 00 .
  //    0802 
  //    > cir 0a 4000               fmove.l <ea>,fp0
  //    > cir 00 ....
  //    9504 8900 8900 8900 
  //    > cir 10 00000001
  //    > cir 00 ....
  //    0802 0802 0802 0802 
  //    > cir 0a 6000               fmove.l fp0,<ea>
  //    > cir 00 ....
  //    8900 B104 0802 0802 
  //    > cir 10 .
  //    00000001 
  //    > cir 00 ....
  //    0802 0802 0802 0802 
  //    > cir 0a 6000               fmove.l fp0,<ea>
  //    > cir 04 .                  fsave
  //    1F38 
  //    > cir 10 ..............
  //    3C0EFFFF 00000001 00000000 00000002 FFFF0000 3FFF0000 20000000 00000000 00000000 00000000 00000200 60000000 0F800000 60006000 
  //    > cir 00 ....
  //    0802 0802 0802 0802 
  //    > cir 06 1F38               frestore
  //    > cir 06 .
  //    1F38 
  //    > cir 10 60006000 0F800000 60000000 00000200 00000000 00000000 00000000 20000000 3FFF0000 FFFF0000 00000002 00000000 00000001 3C0EFFFF
  //    > cir 00 ....
  //    8900 B104 0802 0802         fmove.l fp0,<ea>の続き
  //    > cir 10 .
  //    00000001 
  //    > cir 00 ....
  //    0802 0802 0802 0802 
  //    --------------------------------

  public static final boolean CIR_DEBUG_TRACE = false;

  //CIR
  //    0x00  word  read         response CIR
  //    0x02  word        write  control CIR
  //    0x04  word  read         save CIR
  //    0x06  word  read  write  restore CIR
  //    0x08  word  read  write  operation word CIR       MC68882のみ。MC68881ではwriteは無視、readは-1
  //    0x0a  word        write  command CIR
1 2 3