MicroDouble.java
上传用户:hygd004
上传日期:2022-07-01
资源大小:246k
文件大小:135k
源码类别:

J2ME

开发平台:

Java

  1.           lo = negate(LN2_LO);
  2.           k = -1;
  3.         }
  4.       } else {
  5.         long tmp = mul(INV_LN2, d);
  6.         if (xsb == 0) {
  7.           tmp = add(tmp, ONE_HALF);
  8.         } else {
  9.           tmp = sub(tmp, ONE_HALF);
  10.         }
  11.         k = intValue(add(mul(INV_LN2, d), 
  12.                 (xsb == 0) ? ONE_HALF : negate(ONE_HALF)));
  13.         long t = intToDouble(k);
  14.         hi = sub(d, mul(t, LN2_HI)); //  t*ln2_hi is exact here 
  15.         lo = mul(t, LN2_LO);
  16.       }
  17.       d = sub(hi, lo);
  18.       c = sub(sub(hi, d), lo);
  19.     } 
  20.     else if(hx < 0x3c900000) { // when |x|<2**-54, return x 
  21.       return d;
  22.     }
  23.     else {
  24.       k = 0;
  25.       c = 0;
  26.     }
  27.     // x is now in primary range 
  28.     long hfx = scalbn(d, -1);
  29.     long hxs = mul(d, hfx);
  30.     long r1 = add(ONE, mul(hxs, add(Q1, mul(hxs, add(Q2, mul(hxs, 
  31.             add(Q3, mul(hxs, add(Q4, mul(hxs, Q5))))))))));
  32.     long t = sub(THREE, mul(r1, hfx));
  33.     long e = mul(hxs, div(sub(r1, t), sub(SIX, mul(d, t))));
  34.     if(k==0) return sub(d, sub(mul(d, e), hxs)); // c is 0
  35.     else {
  36.       e = sub(sub(mul(d, sub(e, c)), c), hxs);
  37.       if (k == -1) return sub(scalbn(sub(d, e), -1), ONE_HALF);
  38.       if(k==1) 
  39.         if (lt(d, negate(ONE_FOURTH))) return negate(scalbn(sub(e, add(d, 
  40.                 ONE_HALF)), 1));
  41.         else return add(ONE, scalbn(sub(d, e), 1));
  42.         if (k <= -2 || k>56) { // suffice to return exp(x)-1 
  43.           y = sub(ONE, sub(e, d));
  44.           y = setHI(y, getHI(y) + (k << 20)); // add k to y's exponent 
  45.           return sub(y, ONE);
  46.         }
  47.         t = ONE;
  48.         if(k<20) {
  49.           t = setHI(t, 0x3ff00000 - (0x200000>>k)); // t=1-2^-k 
  50.           y = sub(t, sub(e, d));
  51.           y = setHI(y, getHI(y) + (k << 20)); // add k to y's exponent 
  52.        } else {
  53.          t = setHI(t, ((0x3ff-k)<<20)); // 2^-k 
  54.          y = add(sub(d, add(e, t)), ONE);
  55.          y = setHI(y, getHI(y) + (k << 20)); //add k to y's exponent 
  56.        }
  57.     }
  58.     return y;
  59.   }
  60.   private static final long BP[]       = { ONE, THREE_HALVES };
  61.   private static final long DP_HI[]    = { ZERO, 0x3fe2b80340000000L}; // 5.84962487220764160156e-01 
  62.   private static final long DP_LO[]    = { ZERO, 0x3e4cfdeb43cfd006L}; // 1.35003920212974897128e-08 
  63.   // poly coefs for (3/2)*(log(x)-2s-2/3*s**3 
  64.   private static final long L1         = 0x3fe3333333333303L; // 5.99999999999994648725e-01 
  65.   private static final long L2         = 0x3fdb6db6db6fabffL; //  4.28571428578550184252e-01 
  66.   private static final long L3         = 0x3fd55555518f264dL; //  3.33333329818377432918e-01 
  67.   private static final long L4         = 0x3fd17460a91d4101L; //  2.72728123808534006489e-01 
  68.   private static final long L5         = 0x3fcd864a93c9db65L; //  2.30660745775561754067e-01 
  69.   private static final long L6         = 0x3fca7e284a454eefL; //  2.06975017800338417784e-01 
  70.   private static final long LN2_HI_B   = 0x3fe62e4300000000L; //  6.93147182464599609375e-01 
  71.   private static final long LN2_LO_B   = 0xbe205c610ca86c39L; // -1.90465429995776804525e-09) 0xbe205c610ca86c39 
  72.   private static final long OVT        = 0x3c971547652b82feL; // 8.0085662595372944372e-17) // -(1024-log2(ovfl+.5ulp)) 
  73.   private static final long CP         = 0x3feec709dc3a03fdL; //  9.61796693925975554329e-01 = 2/(3ln2)
  74.   private static final long CP_HI      = 0x3feec709e0000000L; //  9.61796700954437255859e-01 = (float)cp
  75.   private static final long CP_LO      = 0xbe3e2fe0145b01f5L; // -7.02846165095275826516e-09 = tail of cp_h
  76.   private static final long INV_LN2_HI = 0x3ff7154760000000L; //  1.44269502162933349609e+00 = 24b 1/ln2
  77.   private static final long INV_LN2_LO = 0x3e54ae0bf85ddf44L; //  1.92596299112661746887e-08 = 1/ln2 tail
  78.   /**
  79.    * Mimics <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Math.html#pow(double, double)">Math.pow(double, double)</a>.
  80.    */
  81.   public static long pow(long d1, long d2) {
  82.     if (isZero(d2)) {
  83.       return ONE;
  84.     } else if (isNaN(d1) || isNaN(d2)) {
  85.       return NaN;
  86.     }
  87.       
  88.     int i0 = (int) ((ONE  >> 29) ^ 1);
  89.     int i1 = 1 - i0;    
  90.     int hx = getHI(d1);
  91.     int lx = getLO(d1);
  92.     int hy = getHI(d2);
  93.     int ly = getLO(d2);
  94.     int ix = hx & 0x7fffffff;
  95.     int iy = hy & 0x7fffffff;
  96.     // determine if y is an odd int when x < 0
  97.     // yisint = 0 ... y is not an integer
  98.     // yisint = 1 ... y is an odd int
  99.     // yisint = 2 ... y is an even int
  100.     int yisint  = 0;
  101.     if (hx < 0) {
  102.       if (iy >= 0x43400000)
  103.         yisint = 2; // even integer y
  104.       else if(iy >= 0x3ff00000) {
  105.         int k = (iy>>20)-0x3ff; // exponent
  106.         if (k > 20) {
  107.           int j = ly>>>(52-k);
  108.           if ((j<<(52-k)) == ly)
  109.             yisint = 2-(j&1);
  110.         } else if (ly == 0) {
  111.           int j = iy >> (20-k);
  112.           if ((j<<(20-k)) == iy)
  113.             yisint = 2-(j&1);
  114.         }
  115.       }
  116.     }
  117.     // special value of y
  118.     if (ly==0) {
  119.       if (iy == 0x7ff00000) { // y is +-inf
  120.         if (((ix-0x3ff00000)|lx) == 0)
  121.                 return  NaN; // inf**+-1 is NaN 
  122.         else if (ix >= 0x3ff00000) // (|x|>1)**+-inf = inf,0 
  123.                 return (hy>=0)? POSITIVE_INFINITY : ZERO;
  124.         else // (|x|<1)**-,+inf = inf,0 
  125.                 return (hy<0) ? POSITIVE_INFINITY : ZERO;
  126.       } 
  127.       if (iy == 0x3ff00000) { // y is  +-1 
  128.         if (hy < 0)
  129.           return div(ONE, d1);
  130.         else
  131.           return d1;
  132.       }
  133.       if (hy == 0x40000000)
  134.         return mul(d1, d1); // y is  2
  135.       if (hy == 0x3fe00000) { // y is  0.5
  136.         if (hx>=0) // x >= +0 
  137.           return sqrt(d1);
  138.       }
  139.     }
  140.     long ax = abs(d1);
  141.     // special value of x
  142.     if (lx == 0) {
  143.       if (ix==0x7ff00000 || ix==0 || ix==0x3ff00000) {
  144.         long z = ax; // x is +-0,+-inf,+-1
  145.         if (hy < 0 )
  146.           z = div(ONE, z); // z = (1/|x|)
  147.         if (hx < 0) {
  148.           if (((ix-0x3ff00000)|yisint) == 0) {
  149.             z = NaN; // (-1)**non-int is NaN
  150.           } else if (yisint==1) 
  151.             z = negate(z); // (x<0)**odd = -(|x|**odd)
  152.         }
  153.         return z;
  154.       }
  155.     }
  156.   int n = (hx >> 31) + 1;
  157.     /* (x<0)**(non-int) is NaN */
  158.   if ((n | yisint) == 0) {
  159.       return NaN;
  160.     }
  161.     boolean negative = ((n | (yisint-1)) == 0);
  162.     // |y| is huge
  163.     long t1, t2;
  164.     if (iy > 0x41e00000) { // if |y| > 2**31
  165.       if (iy > 0x43f00000){ // if |y| > 2**64, must o/uflow 
  166.         if (ix <= 0x3fefffff) {
  167.           return ((hy < 0) ? POSITIVE_INFINITY : ZERO);
  168.         }
  169.         return ((hy > 0) ? POSITIVE_INFINITY : ZERO);
  170.       }
  171.       // over/underflow if x is not close to one
  172.       if (ix < 0x3fefffff) {
  173.         if (negative) {
  174.           return ((hy < 0) ? NEGATIVE_INFINITY : NEGATIVE_ZERO);
  175.         } else {
  176.           return ((hy < 0) ? POSITIVE_INFINITY : ZERO);
  177.         }
  178.       }
  179.       if (ix > 0x3ff00000) {
  180.         if (negative) {
  181.           return ((hy > 0) ? NEGATIVE_INFINITY : NEGATIVE_ZERO);
  182.         } else {
  183.           return ((hy > 0) ? POSITIVE_INFINITY : ZERO);
  184.         }
  185.       }
  186.       // now |1-x| is tiny <= 2**-20, suffice to compute
  187.       // log(x) by x-x^2/2+x^3/3-x^4/4
  188.       long t = sub(ax, ONE); // t has 20 trailing zeros
  189.       long w = mul(mul(t, t), sub(ONE_HALF, mul(t, 
  190.               sub(ONE_THIRD, mul(t, ONE_FOURTH)))));
  191.       long u = mul(INV_LN2_HI, t); // INV_LN2_HI has 21 sig. bits
  192.       long v = sub(mul(t, INV_LN2_LO), mul(w, INV_LN2));
  193.       t1 = setLO(add(u, v), 0);
  194.       t2 = sub(v, sub(t1, u));
  195.     } else {
  196.       n = 0;
  197.       // take care subnormal number
  198.       if (ix<0x00100000) {
  199.         ax = scalbn(ax, 53);
  200.         n -= 53;
  201.         ix = getHI(ax);
  202.       }
  203.       n  += ((ix)>>20) - 0x3ff;
  204.       int j  = ix & 0x000fffff;
  205.       // determine interval 
  206.       ix = j|0x3ff00000; // normalize ix
  207.       int k;
  208.       if (j <= 0x3988E)
  209.         k=0; // |x|<sqrt(3/2)
  210.       else if (j < 0xBB67A)
  211.         k=1; // |x|<sqrt(3)
  212.       else {
  213.         k = 0;
  214.         n+=1;
  215.         ix -= 0x00100000;
  216.       }
  217.       ax = setHI(ax, ix);
  218.       // compute ss = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5)
  219.       long u = sub(ax, BP[k]); // bp[0]=1.0, bp[1]=1.5
  220.       long v = div(ONE, add(ax, BP[k]));
  221.       long ss = mul(u, v);
  222.       long s_h = setLO(ss, 0);
  223.       // t_h=ax+bp[k] High 
  224.       long t_h = setHI(ZERO, ((ix>>1)|0x20000000)+0x00080000+(k<<18)); 
  225.       long t_l = sub(ax, sub(t_h, BP[k]));
  226.       long s_l = mul(v, sub(sub(u, mul(s_h, t_h)), mul(
  227.               s_h, t_l)));
  228.       // compute log(ax)
  229.       long s2 = mul(ss, ss);
  230.       long r = mul(mul(s2, s2), add(L1, mul(s2, add(L2, mul(
  231.               s2, add(L3, mul(s2, add(L4, mul(s2, add(L5, mul(
  232.               s2, L6)))))))))));
  233.       r = add(r, mul(s_l, add(s_h, ss)));
  234.       s2 = mul(s_h, s_h);
  235.       t_h = setLO(add(add(THREE, s2), r), 0);
  236.       t_l = sub(r, sub(sub(t_h, THREE), s2));
  237.       // u+v = ss*(1+...) 
  238.       u = mul(s_h, t_h);
  239.       v = add(mul(s_l, t_h), mul(t_l, ss));
  240.       // 2/(3log2)*(ss+...) 
  241.       long p_h = setLO(add(u, v), 0);
  242.       long p_l = sub(v, sub(p_h, u));
  243.       long z_h = mul(CP_HI, p_h); // cp_h+cp_l = 2/(3*log2) 
  244.       long z_l = add(add(mul(CP_LO, p_h), mul(p_l, CP)), DP_LO[k]);
  245.       // log2(ax) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l 
  246.       long t = intToDouble(n);
  247.       t1 = setLO(add(add(add(z_h, z_l), DP_HI[k]), t), 0);
  248.       t2 = sub(z_l, sub(sub(sub(t1, t), DP_HI[k]), z_h));
  249.     }
  250.     // split up y into y1+y2 and compute (y1+y2)*(t1+t2) 
  251.     long y1 = setLO(d2, 0);
  252.     long p_l = add(mul(sub(d2, y1), t1), mul(d2, t2));
  253.     long p_h = mul(y1, t1);
  254.     long z = add(p_l, p_h);
  255.     int j = getHI(z);
  256.     int i = getLO(z);
  257.     if (j >= 0x40900000) { // z >= 1024
  258.       if ((((j-0x40900000)|i) != 0) // if z > 1024
  259.           || gt(add(p_l, OVT), sub(z, p_h))) {
  260.         return negative ? NEGATIVE_INFINITY : POSITIVE_INFINITY;
  261.       }
  262.     } else if((j&0x7fffffff) >= 0x4090cc00) { // z <= -1075
  263.       if ((((j-0xc090cc00)|i) != 0) // z < -1075
  264.           || le(p_l, sub(z, p_h))) {
  265.         return negative ? NEGATIVE_ZERO : ZERO;
  266.       }
  267.     }
  268.     // compute 2**(p_h+p_l)
  269.     i = j&0x7fffffff;
  270.     int k = (i>>20)-0x3ff;
  271.     n = 0;
  272.     if (i > 0x3fe00000) { // if |z| > 0.5, set n = [z+0.5]
  273.       n = j + (0x00100000>>(k+1));
  274.       k = ((n&0x7fffffff)>>20) - 0x3ff; // new k for n
  275.       long t = ZERO;
  276.       t = setHI(t, (n&~(0x000fffff>>k)));
  277.       n = ((n&0x000fffff)|0x00100000)>>(20-k);
  278.       if (j < 0) n = -n;
  279.       p_h = sub(p_h, t);
  280.     }
  281.     long t = setLO(add(p_l, p_h), 0);
  282.     long u = mul(t, LN2_HI_B);
  283.     long v = add(mul(sub(p_l, sub(t, p_h)), LN2), mul(t, 
  284.             LN2_LO_B));
  285.     z = add(u, v);
  286.     long w = sub(v, sub(z, u));
  287.     t = mul(z, z);
  288.     t1 = sub(z, mul(t, add(P1, mul(t, add(P2, mul(t, add(P3,
  289.             mul(t, add(P4, mul(t, P5))))))))));
  290.     long r = sub(div(mul(z, t1), sub(t1, TWO)), add(
  291.             w, mul(z, w)));
  292.     z = sub(ONE, sub(r, z));
  293.     j = getHI(z);
  294.     j += (n<<20);
  295.     if ((j>>20) <= 0) {
  296.       z = scalbn(z,n); //subnormal output
  297.     } else {
  298.       i = getHI(z);
  299.       i += (n << 20);
  300.       z = setHI(z, i);
  301.     }
  302.     if (negative) {
  303.       z = negate(z);
  304.     }
  305.     return z;
  306.   }
  307.   
  308.   /**
  309.    * Returns the logarithm of a <code>double</code> value using a specified
  310.    * base.  For most arguments, the return value is computed as:
  311.    * <code>log(d) / log(base)</code>.  If <code>base</code> is <code>E</code> or 
  312.    * <code>10</code> the dedicated log function is used.  If <code>base</code>
  313.    * is zero, infinite, <code>NaN</code>, or negative, <code>NaN</code> is
  314.    * returned.
  315.    *
  316.    * @param   d   a <code>double</code> value greater than <code>0.0</code>.
  317.    * @param   base   a <code>double</code> value greater than <code>0.0</code>.
  318.    * @return  the value log<sub><code>base</code></sub>&nbsp;<code>d</code>
  319.    */
  320.   public static long log(long d, long base) {
  321.     if (base == E) {
  322.       return log(d);
  323.     } else if (base == TEN) {
  324.       return log10(d);
  325.     } else if (isZero(base) || isInfinite(base) || isNaN(base) 
  326.             || unpackSign(base)) {
  327.       return NaN;
  328.     }
  329.     return div(log(d), log(base));
  330.   }
  331.   private static final long IVLN10    = 0x3FDBCB7B1526E50EL; // 4.34294481903251816668e-01
  332.   private static final long LOG10_2HI = 0x3FD34413509F6000L; // 3.01029995663611771306e-01
  333.   private static final long LOG10_2LO = 0x3D59FEF311F12B36L; // 3.69423907715893078616e-13
  334.   /**
  335.    * Returns the base 10 logarithm of a <code>double</code>
  336.    * value.  
  337.    *
  338.    * @param   d   a <code>double</code> value greater than <code>0.0</code>.
  339.    * @return  the value log<sub>10</sub>&nbsp;<code>d</code>
  340.    */
  341.   public static long log10(long d) {
  342.     if (isZero(d)) {
  343.       return NEGATIVE_INFINITY;
  344.     } else if (isNaN(d) || unpackSign(d)) {
  345.       return NaN;
  346.     } else if (d == POSITIVE_INFINITY) {
  347.       return d;
  348.     }
  349.     int n = ilogb(d);
  350.     if (n < 0) {
  351.       n++;
  352.     }
  353.     d = scalbn(d, -n);
  354.     long dn = intToDouble(n);
  355.     return add(mul(dn, LOG10_2HI), add(mul(dn, LOG10_2LO), 
  356.             mul(IVLN10, log(d))));
  357.   }
  358.   
  359.   private static final long LG1 = 0x3fe5555555555593L;  // 6.666666666666735130e-01
  360.   private static final long LG2 = 0x3fd999999997fa04L;  // 3.999999999940941908e-01
  361.   private static final long LG3 = 0x3fd2492494229359L;  // 2.857142874366239149e-01
  362.   private static final long LG4 = 0x3fcc71c51d8e78afL;  // 2.222219843214978396e-01
  363.   private static final long LG5 = 0x3fc7466496cb03deL;  // 1.818357216161805012e-01
  364.   private static final long LG6 = 0x3fc39a09d078c69fL;  // 1.531383769920937332e-01
  365.   private static final long LG7 = 0x3fc2f112df3e5244L;  // 1.479819860511658591e-01
  366.   /**
  367.    * Mimics <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Math.html#log(double)">Math.log(double)</a>.
  368.    */
  369.   public static long log(long d) {
  370.     if (isZero(d)) {
  371.       return NEGATIVE_INFINITY;
  372.     } else if (isNaN(d) || unpackSign(d)) {
  373.       return NaN;
  374.     } else if (d == POSITIVE_INFINITY) {
  375.       return d;
  376.     }
  377.     int hx = getHI(d); // high word of x 
  378.     int k=0;
  379.     if (hx < 0x00100000) { // x < 2**-1022
  380.       k -= 54;
  381.       d = scalbn(d, 54);
  382.       hx = getHI(d);
  383.     } 
  384.     k += (hx>>20)-1023;
  385.     hx &= 0x000fffff;
  386.     int i = (hx+0x95f64)&0x100000;
  387.     d = setHI(d, hx|(i^0x3ff00000)); // normalize x or x/2
  388.     k += (i>>20);
  389.     long f = sub(d, ONE);
  390.     if ((0x000fffff&(2+hx))<3) { // |f| < 2**-20
  391.       if (isZero(f)) {
  392.         if (k == 0) {
  393.           return ZERO;
  394.         }
  395.         long dk = intToDouble(k);
  396.         return add(mul(dk, LN2_HI), mul(dk, LN2_LO));
  397.       }
  398.       long R = mul(mul(f, f), sub(ONE_HALF, 
  399.               mul(ONE_THIRD, f)));
  400.       if (k == 0) {
  401.         return sub(f, R);
  402.       } else {
  403.         long dk = intToDouble(k);
  404.         return sub(mul(dk, LN2_HI), sub(sub(R, 
  405.                 mul(dk, LN2_LO)), f));
  406.       }
  407.     }
  408.     long dk = intToDouble(k);
  409.     long s = div(f, add(TWO, f));
  410.     long z = mul(s, s);
  411.     long w = mul(z, z);
  412.     long R = add(mul(w, add(LG2, mul(w, add(LG4, mul(w, LG6))))),
  413.             mul(z, add(LG1, mul(w, add(LG3, mul(w, add(LG5, 
  414.             mul(w, LG7))))))));
  415.     i = (hx - 0x6147a) | (0x6b851 - hx);
  416.     if (i > 0) {
  417.       long hfsq = mul(scalbn(f, -1), f);
  418.       if (k == 0) {
  419.         return sub(f, sub(hfsq, mul(s, add(hfsq, R))));
  420.       } else {
  421.         return sub(mul(dk, LN2_HI), sub(sub(hfsq, 
  422.                add(mul(s, add(hfsq, R)), mul(dk, LN2_LO))), f));
  423.       }
  424.     } else if (k==0) {
  425.       return sub(f, mul(s, sub(f, R)));
  426.     } 
  427.     return sub(mul(dk, LN2_HI), sub(sub(mul(s, 
  428.             sub(f, R)), mul(dk, LN2_LO)), f));
  429.   }
  430.   private static final long LP1 = 0x3FE5555555555593L; // 6.666666666666735130e-01
  431.   private static final long LP2 = 0x3FD999999997FA04L; // 3.999999999940941908e-01
  432.   private static final long LP3 = 0x3FD2492494229359L; // 2.857142874366239149e-01
  433.   private static final long LP4 = 0x3FCC71C51D8E78AFL; // 2.222219843214978396e-01
  434.   private static final long LP5 = 0x3FC7466496CB03DEL; // 1.818357216161805012e-01
  435.   private static final long LP6 = 0x3FC39A09D078C69FL; // 1.531383769920937332e-01
  436.   private static final long LP7 = 0x3FC2F112DF3E5244L; // 1.479819860511658591e-01
  437.   /**
  438.    * Returns the natural logarithm of <code>1 + d</code>, computed in a way 
  439.    * that is accurate even when the value of d is close to zero.
  440.    *
  441.    * @param   d   a <code>double</code> value greater than <code>-1.0</code>.
  442.    * @return  the value ln&nbsp;<code>d</code>, the natural logarithm of
  443.    *          <code>d + 1</code>.
  444.    * @see #log(long)
  445.    * @see #expm1(long)
  446.    */
  447.   public static long log1p(long d) {
  448.     int hx = getHI(d);
  449.     int ax = hx & 0x7fffffff;
  450.     int k = 1;
  451.     int hu = 0;
  452.     long f = 0;
  453.     if (hx < 0x3FDA827A) { // x < 0.41422 
  454.       if(ax>=0x3ff00000) { // x <= -1.0 
  455.         if (d == NEGATIVE_ONE) return NEGATIVE_INFINITY; // log1p(-1)=+inf 
  456.         else return NaN; // log1p(x<-1)=NaN
  457.       }
  458.       if(ax<0x3e200000) { // |x| < 2**-29 
  459.         if(ax<0x3c900000) // |x| < 2**-54 
  460.           return d;
  461.         else
  462.           return sub(d, scalbn(mul(d, d), -1));
  463.       }
  464.       if(hx>0||hx<=0xbfd2bec3) {
  465.         k=0;f=d;hu=1;} // -0.2929<x<0.41422 
  466.     } 
  467.     if (hx >= 0x7ff00000) return d;
  468.     long u;
  469.     long c = 0;
  470.     if(k!=0) {
  471.       if(hx<0x43400000) {
  472.         u = add(ONE, d);
  473.         hu = getHI(u); // high word of u 
  474.         k  = (hu>>20)-1023;
  475.         c  = (k > 0) ? sub(ONE, sub(u, d)) : sub(d, sub(u, 
  476.                 ONE)); // correction term 
  477.         c  = div(c, u);
  478.       } else {
  479.         u  = d;
  480.         hu = getHI(u); // high word of u 
  481.         k  = (hu>>20)-1023;
  482.         c  = ZERO;
  483.       }
  484.       hu &= 0x000fffff;
  485.       if(hu<0x6a09e) {
  486.         u = setHI(u, hu|0x3ff00000); // normalize u 
  487.       } else {
  488.         k += 1;
  489.         u = setHI(u, hu|0x3fe00000); // normalize u/2 
  490.         hu = (0x00100000-hu)>>2;
  491.       }
  492.       f = add(u, NEGATIVE_ONE);
  493.     }
  494.     long hfsq= scalbn(mul(f, f), -1);
  495.     long R;
  496.     long dk = intToDouble(k);
  497.     if(hu==0) { // |f| < 2**-20 
  498.       if(isZero(f)) {
  499.         if(k==0) {
  500.           return ZERO;  
  501.         } else {
  502.           c = add(c, mul(dk, LN2_LO)); 
  503.           return add(mul(dk, LN2_HI), c);
  504.         }
  505.       }
  506.       R = mul(hfsq, sub(ONE, div(scalbn(f, 2), THREE)));
  507.       if(k==0) {
  508.         return sub(f, R); 
  509.       } else {
  510.         return sub(mul(dk, LN2_HI), sub(sub(
  511.                 R, add(mul(dk, LN2_LO), c)), f));
  512.       }
  513.     }
  514.     long s = div(f, add(TWO, f));
  515.     long z = mul(s, s);
  516.     R = mul(z, add(LP1, mul(z, add(LP2, mul(z, add(LP3, mul(
  517.             z, add(LP4, mul(z, add(LP5, mul(z, add(LP6, mul(z, 
  518.             LP7)))))))))))));
  519.     if(k==0) {
  520.       return sub(f, sub(hfsq, mul(s, add(hfsq, R))));
  521.     } else {
  522.       return sub(mul(dk, LN2_HI), sub(sub(hfsq, add(
  523.               mul(s, add(hfsq, R)), add(mul(dk, LN2_LO), c))), f));
  524.     }
  525.   }
  526.   
  527.   /**
  528.    * Mimics <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Math.html#sin(double)">Math.sin(double)</a>.
  529.    */
  530.   public static long sin(long d) {
  531.     int ix = getHI(d) & 0x7fffffff;
  532.     if (ix <= 0x3fe921fb) {
  533.       // |x| ~< pi/4 
  534.       return kernelSin(d, ZERO, 0);
  535.     } else if (ix >= 0x7ff00000) {
  536.       // sin(Inf or NaN) is NaN 
  537.       return NaN;
  538.     } else {
  539.       // argument reduction needed 
  540.       long[] y = new long[2];
  541.       int n = remPio2(d, y);
  542.       switch(n&3) {
  543.         case 0:
  544.           return  kernelSin(y[0], y[1], 1);
  545.         case 1:
  546.           return  kernelCos(y[0], y[1]);
  547.         case 2:
  548.           return negate(kernelSin(y[0], y[1], 1));
  549.         default:
  550.           return negate(kernelCos(y[0], y[1]));
  551.       }
  552.     }
  553.   }
  554.   /**
  555.    * Mimics <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Math.html#cos(double)">Math.cos(double)</a>.
  556.    */
  557.   public static long cos(long d) {
  558.     // High word of x.
  559.     int ix = getHI(d) & 0x7fffffff;
  560.     // |x| ~< pi/4
  561.     if (ix <= 0x3fe921fb) {
  562.       return kernelCos(d, ZERO);
  563.     } else if (ix >= 0x7ff00000) {
  564.       // cos(Inf or NaN) is NaN
  565.       return NaN;
  566.     } else {
  567.       // argument reduction needed
  568.       long y[] = new long[2];
  569.       int n = remPio2(d,y);
  570.       switch(n&3) {
  571.         case 0: 
  572.           return kernelCos(y[0],y[1]);
  573.         case 1: 
  574.           return negate(kernelSin(y[0],y[1],1));
  575.         case 2: 
  576.           return negate(kernelCos(y[0],y[1]));
  577.         default:
  578.           return kernelSin(y[0],y[1],1);
  579.       }
  580.     }
  581.   }
  582.   /**
  583.    * Mimics <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Math.html#tan(double)">Math.tan(double)</a>.
  584.    */
  585.   public static long tan(long d) {
  586.     // |x| ~< pi/4 
  587.     int ix = getHI(d) & 0x7fffffff;
  588.     if (ix <= 0x3fe921fb) {
  589.       return kernelTan(d, ZERO, 1);
  590.     } else if (ix >= 0x7ff00000) {
  591.       // tan(Inf or NaN) is NaN
  592.       return NaN;
  593.     } else {
  594.       // argument reduction needed 
  595.       long[] y = new long [2];
  596.       int n = remPio2(d, y);
  597.       // 1 -- n even -1 -- n odd
  598.       return kernelTan(y[0], y[1], 1-((n&1)<<1));
  599.     }
  600.   }
  601.         
  602.   private static final long PIO4    = 0x3fe921fb54442d18L; // 7.85398163397448278999e-01 
  603.   private static final long PIO4_LO = 0x3c81a62633145c07L; // 3.06161699786838301793e-17 
  604.   private static final long T0      = 0x3fd5555555555563L; // 3.33333333333334091986e-01 
  605.   private static final long T1      = 0x3fc111111110fe7aL; // 1.33333333333201242699e-01
  606.   private static final long T2      = 0x3faba1ba1bb341feL; // 5.39682539762260521377e-02 
  607.   private static final long T3      = 0x3f9664f48406d637L; // 2.18694882948595424599e-02 
  608.   private static final long T4      = 0x3f8226e3e96e8493L; // 8.86323982359930005737e-03 
  609.   private static final long T5      = 0x3f6d6d22c9560328L; // 3.59207910759131235356e-03 
  610.   private static final long T6      = 0x3f57dbc8fee08315L; // 1.45620945432529025516e-03 
  611.   private static final long T7      = 0x3f4344d8f2f26501L; // 5.88041240820264096874e-04 
  612.   private static final long T8      = 0x3f3026f71a8d1068L; // 2.46463134818469906812e-04 
  613.   private static final long T9      = 0x3f147e88a03792a6L; // 7.81794442939557092300e-05 
  614.   private static final long T10     = 0x3f12b80f32f0a7e9L; // 7.14072491382608190305e-05 
  615.   private static final long T11     = 0xbef375cbdb605373L; // -1.85586374855275456654e-05 
  616.   private static final long T12     = 0x3efb2a7074bf7ad4L; // 2.59073051863633712884e-05 
  617.         
  618.   private static long kernelTan(long x, long y, int iy) {
  619.     int hx = getHI(x); // high word of x
  620.     int ix = hx & 0x7fffffff;
  621.     if (ix < 0x3e300000) { // x < 2**-28 
  622.       if (intValue(x) == 0) {
  623.         if (((ix | getLO(x)) | (iy + 1)) == 0) {
  624.           return POSITIVE_INFINITY;
  625.         } else if (iy == 1) {
  626.           return x;
  627.         } else {
  628.           /* compute -1 / (x+y) carefully */
  629.           long w = add(x, y);
  630.           long z = setLO(w, 0);
  631.           long v = sub(y, sub(z, x));
  632.           long a = div(NEGATIVE_ONE, w);
  633.           long t = setLO(a, 0);
  634.           long s = add(ONE, mul(t, z));
  635.           return add(t, mul(a, add(s, mul(t, v))));
  636.         }
  637.       }
  638.     }
  639.     if (ix>=0x3FE59428) {
  640.       // |x|>=0.6744 
  641.       if (hx<0) {
  642.         x = negate(x);
  643.         y = negate(y);
  644.       }
  645.       x = add(sub(PIO4, x), sub(PIO4_LO, y));
  646.       y = ZERO;
  647.     }
  648.     long z = mul(x, x);
  649.     long w = mul(z, z);
  650.     // Break x^5*(T[1]+x^2*T[2]+...) into
  651.     // x^5(T[1]+x^4*T[3]+...+x^20*T[11]) + 
  652.     // x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12]))
  653.     long r = add(T1, mul(w, add(T3, mul(w, add(T5, mul(w, add(
  654.             T7, mul(w, add(T9, mul(w, T11))))))))));
  655.     long v = mul(z, add(T2, mul(w, add(T4, mul(w, add(T6, 
  656.             mul(w, add(T8, mul(w, add(T10, mul(w, T12)))))))))));
  657.     long s = mul(z, x);
  658.     r = add(add(y, mul(z, add(mul(s, add(r, v)), y))), mul(T0, s));
  659.     w = add(x, r);
  660.     if (ix >= 0x3FE59428) {
  661.       v = intToDouble(iy);
  662.       return mul(intToDouble(1-((hx>>30)&2)), sub(v, mul(
  663.               TWO, sub(x, sub(div(mul(w, w), add(
  664.               w, v)), r)))));
  665.     }
  666.     if (iy == 1) {
  667.       return w;
  668.     } else { // if allow error up to 2 ulp, simply return -1.0/(x+r) here 
  669.       // compute -1.0/(x+r) accurately 
  670.       z = setLO(w, 0);
  671.       v = sub(r, sub(z, x)); // z+v = r+x
  672.       long a = div(NEGATIVE_ONE, w); // a = -1.0/w 
  673.       long t = setLO(a, 0);
  674.       s = add(ONE, mul(t, z));
  675.       return add(t, mul(a, add(s, mul(t, v))));
  676.     }
  677.   }
  678.         
  679.   private static long S1 = 0xBFC5555555555549L; // -1.66666666666666324348e-01
  680.   private static long S2 = 0x3F8111111110F8A6L; // 8.33333333332248946124e-03 
  681.   private static long S3 = 0xBF2A01A019C161D5L; // -1.98412698298579493134e-04 
  682.   private static long S4 = 0x3EC71DE357B1FE7DL; // 2.75573137070700676789e-06  
  683.   private static long S5 = 0xBE5AE5E68A2B9CEBL; // -2.50507602534068634195e-08
  684.   private static long S6 = 0x3DE5D93A5ACFD57CL; // 1.58969099521155010221e-10
  685.   private static long kernelSin(long x, long y, int iy) {
  686.     int ix = getHI(x) & 0x7fffffff; // high word of x
  687.     if (ix < 0x3e400000) { // |x| < 2**-27 
  688.       return x;
  689.     }
  690.     long z = mul(x, x);
  691.     long v = mul(z, x);
  692.     long r = add(S2, mul(z, add(S3, mul(z, add(S4, mul(z, add(S5,
  693.             mul(z, S6))))))));
  694.     if (iy == 0) {
  695.       return add(x, mul(v, add(S1, mul(z, r))));
  696.     }
  697.     return sub(x, sub(sub(mul(z, 
  698.             sub(mul(ONE_HALF, y), mul(v, r))), y), mul(v, S1)));
  699.   }
  700.   private static final long C1  = 0x3fa555555555554cL; //  4.16666666666666019037e-02 
  701.   private static final long C2  = 0xbf56c16c16c15177L; // -1.38888888888741095749e-03 
  702.   private static final long C3  = 0x3efa01a019cb1590L; //  2.48015872894767294178e-05 
  703.   private static final long C4  = 0xbe927e4f809c52adL; // -2.75573143513906633035e-07 
  704.   private static final long C5  = 0x3e21ee9ebdb4b1c4L; //  2.08757232129817482790e-09 
  705.   private static final long C6  = 0xbda8fae9be8838d4L; // -1.13596475577881948265e-11 
  706.   private static long kernelCos(long x, long y) {
  707.     int ix = getHI(x) & 0x7fffffff; // ix = |x|'s high word
  708.     if (ix < 0x3e400000) {
  709.       // if x < 2**27
  710.       return ONE;
  711.     }
  712.     long z = mul(x, x);
  713.     long r = mul(z, add(C1, mul(z, add(C2, mul(z, add(C3, 
  714.             mul(z, add(C4, mul(z, add(C5, mul(z, C6)))))))))));
  715.     if (ix < 0x3FD33333) {
  716.       // if |x| < 0.3
  717.       return sub(ONE, sub(mul(ONE_HALF, z), sub(
  718.               mul(z, r), mul(x, y))));
  719.     }
  720.     long qx;
  721.     if (ix > 0x3fe90000) { // x > 0.78125
  722.       qx = 0x3fd2000000000000L; // 0.28125
  723.     } else {
  724.       qx = set(ix-0x00200000, 0); // x/4 
  725.     }
  726.     long hz = sub(mul(ONE_HALF, z), qx);
  727.     long a = sub(ONE, qx);
  728.     return sub(a, (sub(hz, sub(mul(z, r), mul(x, y)))));
  729.   }
  730.         
  731.   private static final long PIO2[] = {
  732.           0x3ff921fb40000000L,  // 1.57079625129699707031e+00 
  733.           0x3e74442d00000000L,  // 7.54978941586159635335e-08 
  734.           0x3cf8469880000000L,  // 5.39030252995776476554e-15 
  735.           0x3b78cc5160000000L,  // 3.28200341580791294123e-22 
  736.           0x39f01b8380000000L,  // 1.27065575308067607349e-29 
  737.           0x387a252040000000L,  // 1.22933308981111328932e-36 
  738.           0x36e3822280000000L,  // 2.73370053816464559624e-44 
  739.           0x3569f31d00000000L   // 2.16741683877804819444e-51 
  740.   };
  741.   
  742.    // Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi 
  743.   private static final int[] TWO_OVER_PI = {
  744.           0xa2f983, 0x6e4e44, 0x1529fc, 0x2757d1, 0xf534dd, 0xc0db62, 
  745.           0x95993c, 0x439041, 0xfe5163, 0xabdebb, 0xc561b7, 0x246e3a, 
  746.           0x424dd2, 0xe00649, 0x2eea09, 0xd1921c, 0xfe1deb, 0x1cb129, 
  747.           0xa73ee8, 0x8235f5, 0x2ebb44, 0x84e99c, 0x7026b4, 0x5f7e41, 
  748.           0x3991d6, 0x398353, 0x39f49c, 0x845f8b, 0xbdf928, 0x3b1ff8, 
  749.           0x97ffde, 0x05980f, 0xef2f11, 0x8b5a0a, 0x6d1f6d, 0x367ecf, 
  750.           0x27cb09, 0xb74f46, 0x3f669e, 0x5fea2d, 0x7527ba, 0xc7ebe5, 
  751.           0xf17b3d, 0x0739f7, 0x8a5292, 0xea6bfb, 0x5fb11f, 0x8d5d08, 
  752.           0x560330, 0x46fc7b, 0x6babf0, 0xcfbc20, 0x9af436, 0x1da9e3, 
  753.           0x91615e, 0xe61b08, 0x659985, 0x5f14a0, 0x68408d, 0xffd880, 
  754.           0x4d7327, 0x310606, 0x1556ca, 0x73a8c9, 0x60e27b, 0xc08c6b};
  755.           
  756.   private static final int[] NPIO2_HW = {
  757.           0x3ff921fb, 0x400921fb, 0x4012d97c, 0x401921fb, 0x401f6a7a, 0x4022d97c,
  758.           0x4025fdbb, 0x402921fb, 0x402c463a, 0x402f6a7a, 0x4031475c, 0x4032d97c,
  759.           0x40346b9c, 0x4035fdbb, 0x40378fdb, 0x403921fb, 0x403ab41b, 0x403c463a,
  760.           0x403dd85a, 0x403f6a7a, 0x40407e4c, 0x4041475c, 0x4042106c, 0x4042d97c,
  761.           0x4043a28c, 0x40446b9c, 0x404534ac, 0x4045fdbb, 0x4046c6cb, 0x40478fdb,
  762.           0x404858eb, 0x404921fb};
  763.           
  764.   private static final long TWO24    = 0x4170000000000000L; // 1.67772160000000000000e+07 
  765.   private static final long INV_PIO2 = 0x3fe45f306dc9c883L; // 6.36619772367581382433e-01 53 bits of 2/pi 
  766.   
  767.   private static final long PIO2_1   = 0x3ff921fb54400000L; // 1.57079632673412561417e+00 first  33 bit of pi/2 
  768.   private static final long PIO2_1T  = 0x3dd0b4611a626331L; // 6.07710050650619224932e-11 pi/2 - pio2_1 
  769.   private static final long PIO2_2   = 0x3dd0b4611a600000L; // 6.07710050630396597660e-11 second 33 bit of pi/2 
  770.   private static final long PIO2_2T  = 0x3ba3198a2e037073L; // 2.02226624879595063154e-21 pi/2 - (pio2_1+pio2_2) 
  771.   private static final long PIO2_3   = 0x3ba3198a2e000000L; // 2.02226624871116645580e-21 third  33 bit of pi/2 
  772.   private static final long PIO2_3T  = 0x397b839a252049c1L; // 8.47842766036889956997e-32 pi/2 - (pio2_1+pio2_2+pio2_3) 
  773.   // Return the remainder of x % pi/2 in y[0]+y[1].  This is rather complex.
  774.   // Perhaps it would make sense to do something simpler.
  775.   private static int remPio2(long x, long[] y) {
  776.     int hx = getHI(x); // high word of x
  777.     int ix = hx&0x7fffffff;
  778.     if (ix <= 0x3fe921fb) {
  779.       // |x| ~<= pi/4 , no need for reduction 
  780.       y[0] = x;
  781.       y[1] = ZERO;
  782.       return 0;
  783.     }
  784.     if (ix < 0x4002d97c) {
  785.       // |x| < 3pi/4, special case with n=+-1
  786.       long a = PIO2_1;
  787.       long b = (ix == 0x3ff921fb) ? PIO2_2T : PIO2_1T;
  788.       if (hx > 0) {
  789.         a = negate(a);
  790.         b = negate(b);
  791.       }
  792.       long z = add(x, a);
  793.       y[0] = add(z, b);
  794.       y[1] = add(sub(z, y[0]), b);
  795.       return (hx > 0) ? 1 : -1;
  796.     }
  797.     if (ix <= 0x413921fb) { // |x| ~<= 2^19*(pi/2), medium size 
  798.       long t = abs(x);
  799.       long fn = rint(mul(t, INV_PIO2));
  800.       int n = intValue(fn);
  801.       long r = sub(t, mul(fn, PIO2_1));
  802.       long w = mul(fn, PIO2_1T); // 1st round good to 85 bit
  803.       if ((n < 32) && (ix != NPIO2_HW[n-1])) {
  804.         y[0] = sub(r, w); // quick check no cancellation 
  805.       } else {
  806.         int j = ix >> 20;
  807.         y[0] = sub(r, w);
  808.         int i = j - (((getHI(y[0])) >> 20) & 0x7ff);
  809.         if (i > 16) { // 2nd iteration needed, good to 118 
  810.           t  = r;
  811.           w  = mul(fn, PIO2_2);
  812.           r  = sub(t, w);
  813.           w = sub(mul(fn, PIO2_2T), sub(sub(t, r), w));
  814.           y[0] = sub(r, w);
  815.           i = j - (((getHI(y[0])) >> 20) & 0x7ff);
  816.           if (i > 49) { // 3rd iteration need, 151 bits acc
  817.             t  = r;     // will cover all possible cases
  818.             w  = mul(fn, PIO2_3);
  819.             r  = sub(t, w);
  820.             w = sub(mul(fn, PIO2_3T), sub(sub(t, r), w));
  821.             y[0] = sub(r, w);
  822.           }
  823.         }
  824.       }
  825.       y[1] = sub(sub(r, y[0]), w);
  826.       if (hx < 0) {
  827.         y[0] = negate(y[0]);
  828.         y[1] = negate(y[1]);
  829.         return -n;
  830.       } else {
  831.         return n;
  832.       }
  833.     }
  834.     // all other (large) arguments
  835.     if (ix >= 0x7ff00000) {
  836.       // x is inf or NaN 
  837.       y[0] = y[1] = NaN;
  838.       return 0;
  839.     }
  840.     // set z = scalbn(|x|,ilogb(x)-23)
  841.     long z = getLO(x);
  842.     int e0 = (int) ((ix >> 20) - 1046);
  843.     z = setHI(z, ix - (e0 << 20));
  844.     long[] tx = new long[3];
  845.     for (int i=0; i<2; i++) {
  846.       tx[i] = intToDouble(intValue(z));
  847.       z     = scalbn(sub(z, tx[i]), 24);
  848.     }
  849.     tx[2] = z;
  850.     int nx = 3;
  851.     while (isZero(tx[nx-1])) nx--; // skip zero term 
  852.     int n = kernelRemPio2(tx, y, e0, nx);
  853.     if (hx < 0) {
  854.       y[0] = negate(y[0]);
  855.       y[1] = negate(y[1]);
  856.       return -n;
  857.     }
  858.     return n;
  859.   }
  860.   // Work even harder to compute mod pi/2.  This is extremely complex.
  861.   // Perhaps it would make sense to do something simpler.
  862.   private static int kernelRemPio2(long[] x, long[] y, int e0, int nx) {
  863.     // initialize jk
  864.     int jk = 4;
  865.     int jp = jk;
  866.     // determine jx,jv,q0, note that 3>q0 
  867.     int jx =  nx - 1;
  868.     int jv = (e0-3)/24;
  869.     if (jv < 0)  jv = 0;
  870.     int q0 =  e0-24*(jv+1);
  871.     // set up f[0] to f[jx+jk] where f[jx+jk] = two_over_pi[jv+jk]
  872.     int j = jv - jx;
  873.     int m = jx + jk;
  874.     long[] f = new long[20];
  875.     for (int i=0; i<=m; i++, j++) {
  876.       f[i] = (j<0) ? ZERO : intToDouble(TWO_OVER_PI[j]);
  877.     }
  878.     // compute q[0],q[1],...q[jk]
  879.     long[] q = new long[20];
  880.     for (int i=0; i<=jk; i++) {
  881.       long fw = ZERO;
  882.       for (j=0; j<=jx; j++) {
  883.         fw = add(fw, mul(x[j], f[jx+i-j]));
  884.       }
  885.       q[i] = fw;
  886.     }
  887.     
  888.     int jz = jk;
  889.     int n, ih;
  890.     long z;
  891.     int[] iq = new int[20];
  892.     boolean recompute;
  893.     do {
  894.       recompute = false;
  895.       // distill q[] into iq[] reversingly 
  896.       int i;
  897.       for (i=0, j=jz, z=q[jz]; j>0; i++, j--) {
  898.         long fw = intToDouble(intValue(scalbn(z, -24)));
  899.         iq[i] = intValue(sub(z, scalbn(fw, 24)));
  900.         z = add(q[j-1], fw);
  901.       }
  902.       // compute n
  903.       z = scalbn(z, q0); // actual value of z
  904.       z = sub(z, scalbn(floor(scalbn(z, -3)), 3)); // trim off integer >= 8
  905.       z = sub(z, mul(EIGHT, floor(mul(z, ONE_EIGHTH)))); // trim off integer >= 8
  906.       n = intValue(z);
  907.       z = sub(z, intToDouble(n));
  908.       ih = 0;
  909.       if (q0 > 0) { // need iq[jz-1] to determine n
  910.         i  = (iq[jz-1]>>(24-q0));
  911.         n += i;
  912.         iq[jz-1] -= i<<(24-q0);
  913.         ih = iq[jz-1]>>(23-q0);
  914.       } else if (q0==0) {
  915.         ih = iq[jz-1]>>23;
  916.       } else if(ge(z, ONE_HALF)) {
  917.         ih=2;
  918.       }
  919.       if (ih>0) { // q > 0.5
  920.         n += 1;
  921.         int carry = 0;
  922.         for(i=0; i<jz; i++) { // compute 1-q 
  923.           j = iq[i];
  924.           if (carry == 0) {
  925.             if (j != 0) {
  926.               carry = 1;
  927.               iq[i] = 0x1000000- j;
  928.             }
  929.           } else  iq[i] = 0xffffff - j;
  930.         }
  931.         if (q0 > 0) { // rare case: chance is 1 in 12
  932.           switch (q0) {
  933.           case 1:
  934.             iq[jz-1] &= 0x7fffff; break;
  935.           case 2:
  936.             iq[jz-1] &= 0x3fffff; break;
  937.           }
  938.         }
  939.         if (ih == 2) {
  940.           z = sub(ONE, z);
  941.           if (carry != 0) {
  942.             z = sub(z, scalbn(ONE,q0));
  943.           }
  944.         }
  945.       }
  946.       
  947.       // check if recomputation is needed 
  948.       if (isZero(z)) {
  949.         j = 0;
  950.         for (i = jz-1;  i >= jk;  i--)
  951.           j |= iq[i];
  952.         if (j == 0) { // need recomputation
  953.           int k;
  954.           for (k=1; iq[jk-k]==0; k++); // k = no. of terms needed
  955.           for (i=jz+1; i<=jz+k; i++) { // add q[jz+1] to q[jz+k]
  956.             f[jx+i] = intToDouble(TWO_OVER_PI[jv+i]);
  957.             long fw = ZERO;
  958.             for (j=0; j<=jx; j++)
  959.               fw = add(fw, mul(x[j], f[jx+i-j]));
  960.             q[i] = fw;
  961.           }
  962.           jz += k;
  963.           recompute = true;
  964.         }
  965.       }
  966.     } while (recompute);
  967.     // chop off zero terms 
  968.     if (isZero(z)) {
  969.       jz--;
  970.       q0 -= 24;
  971.       while (iq[jz] == 0) {
  972.         jz--;
  973.         q0 -= 24;
  974.       }
  975.     } else { // break z into 24-bit if necessary
  976.       z = scalbn(z,-q0);
  977.       if (ge(z, TWO24)) {
  978.         long fw = intToDouble(intValue(scalbn(z, -24)));
  979.         iq[jz] = intValue(sub(z, scalbn(fw, 24)));
  980.         jz++;
  981.         q0 += 24;
  982.         iq[jz] = intValue(fw);
  983.       } else iq[jz] = intValue(z);
  984.     }
  985.     // convert integer "bit" chunk to floating-point value
  986.     long fw = scalbn(ONE, q0);
  987.     for (int i=jz; i >= 0; i--) {
  988.       q[i] = mul(fw, intToDouble(iq[i]));
  989.       fw = scalbn(fw, -24);
  990.     }
  991.     // compute PIo2[0,...,jp]*q[jz,...,0] 
  992.     long[] fq = new long[20];
  993.     for (int i=jz; i>=0; i--) {
  994.       fw = ZERO;
  995.       for (int k=0; (k<=jp) && (k<=(jz-i)); k++)
  996.         fw = add(fw, mul(PIO2[k], q[i+k]));
  997.       fq[jz-i] = fw;
  998.     }
  999.     // compress fq[] into y[]
  1000.     fw = ZERO;
  1001.     for (int i=jz; i>=0; i--)
  1002.       fw = add(fw, fq[i]);
  1003.     y[0] = (ih==0)? fw : negate(fw);
  1004.     fw = sub(fq[0], fw);
  1005.     for (int i=1; i<=jz; i++)
  1006.       fw = add(fw, fq[i]);
  1007.     y[1] = (ih==0) ? fw: negate(fw); 
  1008.     return n&7;
  1009.   }
  1010.   
  1011.   private static final long PIO2_HI = 0x3FF921FB54442D18L;  // 1.57079632679489655800e+00
  1012.   private static final long PIO2_LO = 0x3C91A62633145C07L;  // 6.12323399573676603587e-17 
  1013.   private static final long PIO4_HI = 0x3FE921FB54442D18L;  // 7.85398163397448278999e-01
  1014.   // coefficient for R(x^2) 
  1015.   private static final long PS0     = 0x3fc5555555555555L;  //  1.66666666666666657415e-01 
  1016.   private static final long PS1     = 0xbfd4d61203eb6f7dL;  // -3.25565818622400915405e-01 
  1017.   private static final long PS2     = 0x3fc9c1550e884455L;  //  2.01212532134862925881e-01 
  1018.   private static final long PS3     = 0xbfa48228b5688f3bL;  // -4.00555345006794114027e-02 
  1019.   private static final long PS4     = 0x3f49efe07501b288L;  //  7.91534994289814532176e-04 
  1020.   private static final long PS5     = 0x3f023de10dfdf709L;  //  3.47933107596021167570e-05 
  1021.   private static final long QS1     = 0xc0033a271c8a2d4bL;  // -2.40339491173441421878e+00 
  1022.   private static final long QS2     = 0x40002ae59c598ac8L;  //  2.02094576023350569471e+00 
  1023.   private static final long QS3     = 0xbfe6066c1b8d0159L;  // -6.88283971605453293030e-01 
  1024.   private static final long QS4     = 0x3fb3b8c5b12e9282L;  //  7.70381505559019352791e-02 
  1025.   private static long pOverQ(long t) {
  1026.     return div(mul(t, add(PS0, mul(t, add(PS1, mul(t, add(PS2,
  1027.             mul(t, add(PS3, mul(t, add(PS4, mul(t, PS5))))))))))),
  1028.             add(ONE, mul(t, add(QS1, mul(t, add(QS2, mul(t,  
  1029.             add(QS3, mul(t, QS4)))))))));
  1030.   }
  1031.   /**
  1032.    * Mimics <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Math.html#asin(double)">Math.asin(double)</a>.
  1033.    */
  1034.   public static final long asin(long d) {
  1035.     int hx = getHI(d);
  1036.     int ix = hx & 0x7fffffff;
  1037.     if (ix>= 0x3ff00000) { // |x|>= 1 
  1038.       if(((ix-0x3ff00000)|getLO(d))==0)
  1039.         // asin(1)=+-pi/2 with inexact
  1040.         return copySign(PIO2_HI, d);
  1041.       return NaN;  // asin(|x|>1) is NaN
  1042.     } else if (ix<0x3fe00000) { // |x|<0.5 
  1043.       if (ix<0x3e400000) { // if |x| < 2**-27
  1044.         return d;
  1045.       }
  1046.       long t = mul(d, d);
  1047.       long w = pOverQ(t);
  1048.       return add(d, mul(d, w));
  1049.     }
  1050.     // 1> |x|>= 0.5
  1051.     long w = sub(ONE, abs(d));
  1052.     long t = scalbn(w, -1);
  1053.     long s = sqrt(t);
  1054.     if(ix>=0x3FEF3333) { // if |x| > 0.975
  1055.       w = pOverQ(t);
  1056.       t = sub(PIO2_HI, sub(scalbn(add(s, mul(s, w)), 1), 
  1057.               PIO2_LO));
  1058.     } else {
  1059.       w  = setLO(s, 0);
  1060.       long c = div(sub(t, mul(w, w)), add(s, w));
  1061.       long r = pOverQ(t);
  1062.       long p = sub(mul(scalbn(s, 1), r), sub(PIO2_LO,
  1063.               scalbn(c, 1)));
  1064.       long q = sub(PIO4_HI, scalbn(w, 1));
  1065.       t = sub(PIO4_HI, sub(p, q));
  1066.     }    
  1067.     return ((hx>0) ? t : negate(t));
  1068.   }
  1069.   /**
  1070.    * Mimics <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Math.html#acos(double)">Math.acos(double)</a>.
  1071.    */
  1072.   public static long acos(long d) {
  1073.     int hx = getHI(d);
  1074.     int ix = hx&0x7fffffff;
  1075.     if (ix >= 0x3ff00000) { // |x| >= 1 
  1076.       if (((ix-0x3ff00000)|getLO(d)) == 0) { // |x|==1
  1077.         if (hx>0) 
  1078.           return ZERO;
  1079.         else
  1080.           return PI; // acos(-1)= pi
  1081.       }
  1082.       return NaN; // acos(|x|>1) is NaN
  1083.     }
  1084.     if (ix < 0x3fe00000) { // |x| < 0.5
  1085.       if (ix <= 0x3c600000)
  1086.         return PIO2_HI; // if|x|<2**-57
  1087.       long z = mul(d, d);
  1088.       long r = pOverQ(z);
  1089.       return sub(PIO2_HI, sub(d, sub(PIO2_LO, mul(d, r))));
  1090.     } else if (hx<0) { // x < -0.5 
  1091.       long z = scalbn(add(ONE, d), -1);
  1092.       long s = sqrt(z);
  1093.       long r = pOverQ(z);
  1094.       long w = sub(mul(r, s), PIO2_LO);
  1095.       return sub(PI, scalbn(add(s, w), 1));
  1096.     } else { // x > 0.5 
  1097.       long z = scalbn(sub(ONE, d), -1);
  1098.       long s = sqrt(z);
  1099.       long df = setLO(s, 0);
  1100.       long c = div(sub(z, mul(df, df)), add(s, df));
  1101.       long r = pOverQ(z);
  1102.       long w = add(mul(r, s), c);
  1103.       return scalbn(add(df, w), 1);
  1104.     }
  1105.   }
  1106.   
  1107.   private static final long atanhi[] = {
  1108.           0x3fddac670561bb4fL,  // 4.63647609000806093515e-01 atan(0.5)hi 
  1109.           0x3fe921fb54442d18L,  // 7.85398163397448278999e-01 atan(1.0)hi
  1110.           0x3fef730bd281f69bL,  // 9.82793723247329054082e-01 atan(1.5)hi
  1111.           0x3ff921fb54442d18L   // 1.57079632679489655800e+00 atan(inf)hi
  1112.   };
  1113.   private static final long atanlo[] = {
  1114.           0x3c7a2b7f222f65e2L,  // 2.26987774529616870924e-17 atan(0.5)lo
  1115.           0x3c81a62633145c07L,  // 3.06161699786838301793e-17 atan(1.0)lo
  1116.           0x3c7007887af0cbbdL,  // 1.39033110312309984516e-17 atan(1.5)lo  
  1117.           0x3c91a62633145c07L   // 6.12323399573676603587e-17 atan(inf)lo  
  1118.   };
  1119.   private static final long AT0  = 0x3fd555555555550dL; //  3.33333333333329318027e-01 
  1120.   private static final long AT1  = 0xbfc999999998ebc4L; // -1.99999999998764832476e-01 
  1121.   private static final long AT2  = 0x3fc24924920083ffL; //  1.42857142725034663711e-01 
  1122.   private static final long AT3  = 0xbfbc71c6fe231671L; // -1.11111104054623557880e-01 
  1123.   private static final long AT4  = 0x3fb745cdc54c206eL; //  9.09088713343650656196e-02 
  1124.   private static final long AT5  = 0xbfb3b0f2af749a6dL; // -7.69187620504482999495e-02 
  1125.   private static final long AT6  = 0x3fb10d66a0d03d51L; //  6.66107313738753120669e-02 
  1126.   private static final long AT7  = 0xbfadde2d52defd9aL; // -5.83357013379057348645e-02 
  1127.   private static final long AT8  = 0x3fa97b4b24760debL; //  4.97687799461593236017e-02 
  1128.   private static final long AT9  = 0xbfa2b4442c6a6c2fL; // -3.65315727442169155270e-02 
  1129.   private static final long AT10 = 0x3f90ad3ae322da11L; //  1.62858201153657823623e-02 
  1130.         
  1131.   /**
  1132.    * Mimics <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Math.html#atan(double)">Math.atan(double)</a>.
  1133.    */
  1134.   public static long atan(long d) {
  1135.     int hx = getHI(d);
  1136.     int ix = hx&0x7fffffff;
  1137.     int id;
  1138.     if(ix>=0x44100000) { // if |x| >= 2^66 
  1139.       if(ix>0x7ff00000||
  1140.         (ix==0x7ff00000&&(getLO(d)!=0)))
  1141.         return NaN;
  1142.       return (hx > 0) ? atanhi[3] : negate(atanhi[3]);
  1143.     } if (ix < 0x3fdc0000) { // |x| < 0.4375
  1144.       if (ix < 0x3e200000) { // |x| < 2^-29 
  1145.         return d;
  1146.       }
  1147.       id = -1;
  1148.     } else {
  1149.       d = abs(d);
  1150.       if (ix < 0x3ff30000) { // |x| < 1.1875 
  1151.         if (ix < 0x3fe60000) { // 7/16 <=|x|<11/16 
  1152.           id = 0;
  1153.           d = div(sub(scalbn(d, 1), ONE), add(TWO, d));
  1154.         } else { // 11/16<=|x|< 19/16 
  1155.           id = 1;
  1156.           d = div(sub(d, ONE), add(d, ONE));
  1157.         }
  1158.       } else {
  1159.         if (ix < 0x40038000) { // |x| < 2.4375 
  1160.           id = 2;
  1161.           d = div(sub(d, THREE_HALVES), add(ONE,
  1162.                   mul(THREE_HALVES, d)));
  1163.         } else { // 2.4375 <= |x| < 2^66 
  1164.           id = 3;
  1165.           d = div(NEGATIVE_ONE, d);
  1166.         }
  1167.       }
  1168.     }
  1169.     // end of argument reduction 
  1170.     long z = mul(d, d);
  1171.     long w = mul(z, z);
  1172.     // break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly 
  1173.     long s1 = mul(z, add(AT0, mul(w, add(AT2, mul(w, add(AT4, 
  1174.             mul(w, add(AT6, mul(w, add(AT8, mul(w, AT10)))))))))));
  1175.     long s2 = mul(w, add(AT1, mul(w, add(AT3, mul(w, add(AT5,
  1176.             mul(w, add(AT7, mul(w, AT9)))))))));
  1177.     if (id<0) {
  1178.       return sub(d, mul(d, add(s1, s2)));
  1179.     } else {
  1180.       z = sub(atanhi[id], sub(sub(mul(d, add(s1, s2)), 
  1181.               atanlo[id]), d));
  1182.       return (hx < 0) ? negate(z): z;
  1183.     }
  1184.   }
  1185.   
  1186.   /**
  1187.    * Returns the hyperbolic cosine of an angle.
  1188.    *
  1189.    * @param   d   an angle, in radians.
  1190.    * @return  the hyperbolic cosine of the argument.
  1191.    */
  1192.   public static long cosh(long d) {
  1193.     if (isNaN(d)) {
  1194.       return NaN;
  1195.     } else if (isInfinite(d)) {
  1196.       return POSITIVE_INFINITY;
  1197.     }
  1198.     
  1199.     int ix = getHI(d) & 0x7fffffff;
  1200.  
  1201.     // |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) 
  1202.     if(ix<0x3fd62e43) {
  1203.       long t = expm1(abs(d));
  1204.       long w = add(ONE, t);
  1205.       if (ix<0x3c800000) return w; // cosh(tiny) = 1 
  1206.       return add(ONE, div(mul(t, t), add(w, w)));
  1207.     }
  1208.     // |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2;
  1209.     if (ix < 0x40360000) {
  1210.       long t = exp(abs(d));
  1211.       return add(scalbn(t, -1), div(ONE_HALF, t));
  1212.     }
  1213.     // |x| in [22, log(maxdouble)] return half*exp(|x|) 
  1214.     if (ix < 0x40862E42)  return scalbn(exp(abs(d)), -1);
  1215.     // |x| in [log(maxdouble), overflowthresold]
  1216.     if (abs(d) <= 0x408633CE8fb9f87dL) {
  1217.       long w = exp(scalbn(abs(d), -1));
  1218.       long t = scalbn(w, -1);
  1219.       return mul(t, w);
  1220.     }
  1221.     // |x| > overflowthresold, cosh(x) overflow 
  1222.     return POSITIVE_INFINITY;
  1223.   }
  1224.   /**
  1225.    * Returns the hyperbolic sine of an angle.
  1226.    *
  1227.    * @param   d   an angle, in radians.
  1228.    * @return  the hyperbolic sine of the argument.
  1229.    */
  1230.   public static long sinh(long d) {
  1231.     if (isNaN(d)) {
  1232.       return NaN;
  1233.     } else if (isInfinite(d)) {
  1234.       return POSITIVE_INFINITY;
  1235.     }
  1236.     
  1237.     int jx = getHI(d);
  1238.     int ix = jx & 0x7fffffff;
  1239.     long h = ONE_HALF;
  1240.     if (jx < 0) h = negate(h);
  1241.     // |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) 
  1242.     if (ix < 0x40360000) { // |x|<22 
  1243.       if (ix<0x3e300000) // |x|<2**-28
  1244.         return d; // sinh(tiny) = tiny with inexact
  1245.       long t = expm1(abs(d));
  1246.       if(ix<0x3ff00000) return mul(h, sub(scalbn(t, 1), mul(t, 
  1247.               div(t, add(t, ONE)))));
  1248.       return mul(h, add(t, div(t, add(t, ONE))));
  1249.     }
  1250.     // |x| in [22, log(maxdouble)] return 0.5*exp(|x|) 
  1251.     if (ix < 0x40862E42)  return mul(h, exp(abs(d)));
  1252.     // |x| in [log(maxdouble), overflowthresold] 
  1253.     if (abs(d) <= 0x408633CE8fb9f87dL) {
  1254.       long w = exp(scalbn(abs(d), -1));
  1255.       long t = mul(h, w);
  1256.       return mul(t, w);
  1257.     }
  1258.     // |x| > overflowthresold, sinh(x) overflow 
  1259.     return copySign(POSITIVE_INFINITY, d);
  1260.   }
  1261.   /**
  1262.    * Returns the hyperbolic tangent of an angle.
  1263.    *
  1264.    * @param   d   an angle, in radians.
  1265.    * @return  the hyperbolic tangent of the argument.
  1266.    */
  1267.   public static long tanh(long d) {
  1268.     if (isNaN(d)) {
  1269.       return NaN;
  1270.     } else if (isInfinite(d)) {
  1271.       return copySign(POSITIVE_INFINITY, d);
  1272.     }
  1273.     
  1274.     int jx = getHI(d);
  1275.     int ix = jx & 0x7fffffff;
  1276.     // |x| < 22 
  1277.     long z;
  1278.     if (ix < 0x40360000) { // |x|<22 
  1279.         if (ix<0x3c800000) // |x|<2**-55 
  1280.           return d; // tanh(small) = small 
  1281.         if (ix>=0x3ff00000) { // |x|>=1  
  1282.           long t = expm1(scalbn(abs(d), 1));
  1283.           z = sub(ONE, div(TWO, add(t, TWO)));
  1284.         } else {
  1285.           long t = expm1(negate(mul(TWO, abs(d))));
  1286.           z = negate(div(t, add(t, TWO)));
  1287.         }
  1288.     // |x| > 22, return +-1 
  1289.     } else {
  1290.       z = ONE;
  1291.     }
  1292.     return (jx>=0) ? z : negate(z);
  1293.   }
  1294.   
  1295.   /**
  1296.    * Returns the arc hyperbolic cosine of an angle.
  1297.    *
  1298.    * @param   d   the value whose arc hyperbolic cosine is to be returned.
  1299.    * @return  the arc hyperbolic cosine of the argument.
  1300.    */
  1301.   public static long acosh(long d) {
  1302.     if (isNaN(d) || lt(d, ONE)) {
  1303.       return NaN;
  1304.     } else if (d == POSITIVE_INFINITY) {
  1305.       return d;
  1306.     } else if (d == ONE) {
  1307.       return ZERO;
  1308.     }
  1309.     int hx = getHI(d);
  1310.     if (hx > 0x41b00000) {
  1311.       return add(log(d), LN2);
  1312.     } else if (hx > 0x40000000) {
  1313.       long t = mul(d, d);
  1314.       return log(sub(scalbn(d, 1), div(ONE, add(d, 
  1315.               sqrt(sub(t, ONE))))));
  1316.     }
  1317.     long t = sub(d, ONE);
  1318.     return log1p(add(t, sqrt(add(scalbn(t, 1), 
  1319.             mul(t, t)))));
  1320.   }
  1321.   /**
  1322.    * Returns the arc hyperbolic sine of an angle.
  1323.    *
  1324.    * @param   d   the value whose arc hyperbolic sine is to be returned.
  1325.    * @return  the arc hyperbolic sine of the argument.
  1326.    */
  1327.   public static long asinh(long d) {
  1328.     int hx = getHI(d);
  1329.     int ix = hx&0x7fffffff;
  1330.     if(ix>=0x7ff00000) return d; // x is inf or NaN 
  1331.     if(ix< 0x3e300000) { // |x|<2**-28
  1332.       return d;
  1333.     } 
  1334.     long w;
  1335.     if(ix>0x41b00000) { /* |x| > 2**28 */
  1336.       w = add(log(abs(d)), LN2);
  1337.     } else if (ix>0x40000000) { /* 2**28 > |x| > 2.0 */
  1338.       long t = abs(d);
  1339.       w = log(add(scalbn(t, 1), div(ONE, add(sqrt(add(
  1340.               mul(d, d), ONE)), t))));
  1341.     } else { /* 2.0 > |x| > 2**-28 */
  1342.       long t = mul(d, d);
  1343.       w = log1p(add(abs(d), div(t, add(ONE, sqrt(add(
  1344.               ONE, t))))));
  1345.     }
  1346.     if(hx>0) return w; else return negate(w);
  1347.   }
  1348.   
  1349.   /**
  1350.    * Returns the arc hyperbolic tangent of an angle.
  1351.    *
  1352.    * @param   d   the value whose arc hyperbolic tangent is to be returned.
  1353.    * @return  the arc hyperbolic tangent of the argument.
  1354.    */
  1355.   public static long atanh(long d) {
  1356.     if (isNaN(d) || gt(d, ONE) || lt(d, NEGATIVE_ONE)) {
  1357.       return NaN;
  1358.     } 
  1359.     boolean negate = unpackSign(d);
  1360.     d = abs(d);
  1361.     if (d == ONE) {
  1362.       d = POSITIVE_INFINITY;
  1363.     } else if (lt(d, ONE_HALF)) {
  1364.       long t = add(d, d);
  1365.       d = scalbn(log1p(add(t, div(mul(t, d), sub(ONE, d)))), -1);
  1366.     } else {
  1367.       d = scalbn(log1p(div(add(d, d), sub(ONE, d))), -1);
  1368.     }
  1369.     if (negate) {
  1370.       d = negate(d);
  1371.     }
  1372.     return d;
  1373.   }
  1374.   
  1375.   /**
  1376.    * Returns the difference of d2 and d1, expressed as a percentage of d1.
  1377.    *
  1378.    * @param   d1   the "starting" value 
  1379.    * @param   d2   the "final" value
  1380.    * @return  100 * ((d2 - d1) / d1)
  1381.    */
  1382.   public static long percentChange(long d1, long d2) {
  1383.     return mul(div(sub(d2, d1), d1), ONE_HUNDRED);
  1384.   }
  1385.   
  1386.   /**
  1387.    * Returns d2 expressed as a percentage of d1
  1388.    *
  1389.    * @param   d1   the "base" value 
  1390.    * @param   d2   the other value
  1391.    * @return  100 * (d2 / d1)
  1392.    */
  1393.   public static long percentTotal(long d1, long d2) {
  1394.     return mul(div(d2, d1), ONE_HUNDRED);
  1395.   }
  1396.   /**
  1397.    * Returns the factorial of d.  If d is not a mathematical integer greater 
  1398.    * than or equal to zero, the return value is NaN.  Use the gamma function
  1399.    * for non-integer values.
  1400.    * <p>
  1401.    * This is a naive implentation.  TODO: make this better.
  1402.    *
  1403.    * @param d a <code>double</code> value.
  1404.    * @return d! 
  1405.    */
  1406.   public static long factorial(long d) {
  1407.     if (isZero(d)) {
  1408.       return ONE;
  1409.     } else if (! isPositiveInteger(d)) {
  1410.       return NaN;
  1411.     }
  1412.     return factorial(ONE, d, ONE);
  1413.   }
  1414.   
  1415.   private static boolean isPositiveInteger(long d) {
  1416.     return (! (unpackSign(d) || isNaN(d) || isInfinite(d) || isZero(d) 
  1417.             || (rint(d) != d)));
  1418.   }
  1419.   
  1420.   private static long factorial(long base, long d1, long d2) {
  1421.     while ((d1 != d2) && (base != POSITIVE_INFINITY)) {
  1422.       base = mul(base, d1);
  1423.       d1 = add(d1, NEGATIVE_ONE);
  1424.     }
  1425.     return base;
  1426.   }
  1427.   
  1428.   /**
  1429.    * Return the number of ways of obtaining an ordered subset of d2 elements 
  1430.    * from a set of d1 elements.  If d1 and d2 are not mathematical integers
  1431.    * than or equal to zero, or if d1 is less than d2, the return value is NaN.
  1432.    *
  1433.    * @param d1 a <code>double</code> value
  1434.    * @param d2 a <code>double</code> value
  1435.    * @return d1! / (d1 - d2)!
  1436.    * @see #factorial(long)
  1437.    * @see #combinations(long, long)
  1438.    */
  1439.   public static long permutations(long d1, long d2) {
  1440.     if (! (isPositiveInteger(d1) && isPositiveInteger(d2) && ge(d1, d2))) {
  1441.       return NaN;
  1442.     }
  1443.     return factorial(ONE, d1, sub(d1, d2));
  1444.   }
  1445.   /**
  1446.    * Return the number of ways of obtaining an unordered subset of d2 elements 
  1447.    * from a set of d1 elements.  Also known as the binomial coefficient.
  1448.    * If d1 and d2 are not mathematical integers greater
  1449.    * than or equal to zero, or if d1 is less than d2, the return value is NaN.
  1450.    *
  1451.    * @param d1 a <code>double</code> value
  1452.    * @param d2 a <code>double</code> value
  1453.    * @return d1! / (d2! * (d1 - d2)!)
  1454.    * @see #factorial(long)
  1455.    * @see #permutations(long, long)
  1456.    */
  1457.   public static long combinations(long d1, long d2) {
  1458.     if (! (isPositiveInteger(d1) && isPositiveInteger(d2) && ge(d1, d2))) {
  1459.       return NaN;
  1460.     }
  1461.     long d3 = sub(d1, d2);
  1462.     if (gt(d3, d2)) {
  1463.       long tmp = d3;
  1464.       d3 = d2;
  1465.       d2 = tmp;
  1466.     }
  1467.     if (isZero(d3)) {
  1468.       d3 = ONE;
  1469.     } else {
  1470.       d3 = div(ONE, factorial(ONE, d3, ONE));
  1471.     }
  1472.     return factorial(d3, d1, d2);
  1473.   }
  1474.   
  1475.   /**
  1476.    * Returns the complete gamma function of d.  
  1477.    *
  1478.    * @param d a <code>double</code> value
  1479.    * @return Gamma(d)
  1480.    * @see #lgamma(long)
  1481.    */
  1482.   public static long gamma(long d) {
  1483.     if (isNaN(d) || isZero(d) 
  1484.         || (lt(d, ZERO) && ((d == NEGATIVE_INFINITY) || (rint(d) == d)))) {
  1485.       return NaN;
  1486.     }
  1487.     return lgamma(d, true);
  1488.   }
  1489.   
  1490.   /**
  1491.    * Returns the natural logarithm of the absolute value of the gamma function
  1492.    * of d.
  1493.    *
  1494.    * @param d a <code>double</code> value
  1495.    * @return Log(|Gamma(d)|)
  1496.    * @see #gamma(long)
  1497.    */
  1498.   public static long lgamma(long d) {
  1499.     return lgamma(d, false);
  1500.   }
  1501.   
  1502.   private static final long A0  = 0x3FB3C467E37DB0C8L; // 7.72156649015328655494e-02
  1503.   private static final long A1  = 0x3FD4A34CC4A60FADL; // 3.22467033424113591611e-01
  1504.   private static final long A2  = 0x3FB13E001A5562A7L; // 6.73523010531292681824e-02
  1505.   private static final long A3  = 0x3F951322AC92547BL; // 2.05808084325167332806e-02
  1506.   private static final long A4  = 0x3F7E404FB68FEFE8L; // 7.38555086081402883957e-03
  1507.   private static final long A5  = 0x3F67ADD8CCB7926BL; // 2.89051383673415629091e-03
  1508.   private static final long A6  = 0x3F538A94116F3F5DL; // 1.19270763183362067845e-03
  1509.   private static final long A7  = 0x3F40B6C689B99C00L; // 5.10069792153511336608e-04
  1510.   private static final long A8  = 0x3F2CF2ECED10E54DL; // 2.20862790713908385557e-04
  1511.   private static final long A9  = 0x3F1C5088987DFB07L; // 1.08011567247583939954e-04
  1512.   private static final long A10 = 0x3EFA7074428CFA52L; // 2.52144565451257326939e-05
  1513.   private static final long A11 = 0x3F07858E90A45837L; // 4.48640949618915160150e-05
  1514.   private static final long TC = 0x3FF762D86356BE3FL; // 1.46163214496836224576e+00
  1515.   private static final long TF = 0xBFBF19B9BCC38A42L; // -1.21486290535849611461e-01
  1516.   // tt = -(tail of tf)
  1517.   private static final long TT = 0xBC50C7CAA48A971FL; // -3.63867699703950536541e-18
  1518.   private static final long TB0 = 0x3FDEF72BC8EE38A2L; // 4.83836122723810047042e-01
  1519.   private static final long TB1 = 0xBFC2E4278DC6C509L; // -1.47587722994593911752e-01
  1520.   private static final long TB2 = 0x3FB08B4294D5419BL; // 6.46249402391333854778e-02
  1521.   private static final long TB3 = 0xBFA0C9A8DF35B713L; // -3.27885410759859649565e-02
  1522.   private static final long TB4 = 0x3F9266E7970AF9ECL; // 1.79706750811820387126e-02
  1523.   private static final long TB5 = 0xBF851F9FBA91EC6AL; // -1.03142241298341437450e-02
  1524.   private static final long TB6 = 0x3F78FCE0E370E344L; // 6.10053870246291332635e-03
  1525.   private static final long TB7 = 0xBF6E2EFFB3E914D7L; // -3.68452016781138256760e-03
  1526.   private static final long TB8 = 0x3F6282D32E15C915L; // 2.25964780900612472250e-03
  1527.   private static final long TB9 = 0xBF56FE8EBF2D1AF1L; // -1.40346469989232843813e-03
  1528.   private static final long TB10 = 0x3F4CDF0CEF61A8E9L; // 8.81081882437654011382e-04
  1529.   private static final long TB11 = 0xBF41A6109C73E0ECL; // -5.38595305356740546715e-04
  1530.   private static final long TB12 = 0x3F34AF6D6C0EBBF7L; // 3.15632070903625950361e-04
  1531.   private static final long TB13 = 0xBF347F24ECC38C38L; // -3.12754168375120860518e-04
  1532.   private static final long TB14 = 0x3F35FD3EE8C2D3F4L; // 3.35529192635519073543e-04
  1533.   private static final long U0  = 0xBFB3C467E37DB0C8L; // -7.72156649015328655494e-02
  1534.   private static final long U1  = 0x3FE4401E8B005DFFL; // 6.32827064025093366517e-01
  1535.   private static final long U2  = 0x3FF7475CD119BD6FL; // 1.45492250137234768737e+00
  1536.   private static final long U3  = 0x3FEF497644EA8450L; // 9.77717527963372745603e-01
  1537.   private static final long U4  = 0x3FCD4EAEF6010924L; // 2.28963728064692451092e-01
  1538.   private static final long U5  = 0x3F8B678BBF2BAB09L; // 1.33810918536787660377e-02
  1539.   private static final long V1  = 0x4003A5D7C2BD619CL; // 2.45597793713041134822e+00, /* 
  1540.   private static final long V2  = 0x40010725A42B18F5L; // 2.12848976379893395361e+00, /* 
  1541.   private static final long V3  = 0x3FE89DFBE45050AFL; // 7.69285150456672783825e-01, /* 
  1542.   private static final long V4  = 0x3FBAAE55D6537C88L; // 1.04222645593369134254e-01, /* 
  1543.   private static final long V5  = 0x3F6A5ABB57D0CF61L; // 3.21709242282423911810e-03, /* 
  1544.   private static final long SB0  = 0xBFB3C467E37DB0C8L; // 7.72156649015328655494e-02, /* 
  1545.   private static final long SB1  = 0x3FCB848B36E20878L; // 2.14982415960608852501e-01, /* 
  1546.   private static final long SB2  = 0x3FD4D98F4F139F59L; // 3.25778796408930981787e-01, /* 
  1547.   private static final long SB3  = 0x3FC2BB9CBEE5F2F7L; // 1.46350472652464452805e-01, /* 
  1548.   private static final long SB4  = 0x3F9B481C7E939961L; // 2.66422703033638609560e-02, /* 
  1549.   private static final long SB5  = 0x3F5E26B67368F239L; // 1.84028451407337715652e-03, /* 
  1550.   private static final long SB6  = 0x3F00BFECDD17E945L; // 3.19475326584100867617e-05, /* 
  1551.   private static final long R1  = 0x3FF645A762C4AB74L; // 1.39200533467621045958e+00, /* 
  1552.   private static final long R2  = 0x3FE71A1893D3DCDCL; // 7.21935547567138069525e-01, /* 
  1553.   private static final long R3  = 0x3FC601EDCCFBDF27L; // 1.71933865632803078993e-01, /*
  1554.   private static final long R4  = 0x3F9317EA742ED475L; // 1.86459191715652901344e-02, /* 
  1555.   private static final long R5  = 0x3F497DDACA41A95BL; // 7.77942496381893596434e-04, /* 
  1556.   private static final long R6  = 0x3EDEBAF7A5B38140L; // 7.32668430744625636189e-06, /* 
  1557.   private static final long W0  = 0x3FDACFE390C97D69L; // 4.18938533204672725052e-01, /* 
  1558.   private static final long W1  = 0x3FB555555555553BL; // 8.33333333333329678849e-02, /* 
  1559.   private static final long W2  = 0xBF66C16C16B02E5CL; // -2.77777777728775536470e-03, /* 
  1560.   private static final long W3  = 0x3F4A019F98CF38B6L; // 7.93650558643019558500e-04, /* 
  1561.   private static final long W4  = 0xBF4380CB8C0FE741L; // -5.95187557450339963135e-04, /* 
  1562.   private static final long W5  = 0x3F4B67BA4CDAD5D1L; // 8.36339918996282139126e-04, /* 
  1563.   private static final long W6  = 0xBF5AB89D0B9E43E4L; // -1.63092934096575273989e-03; /* 
  1564.   /**
  1565.    * Return gamma(x) or ln(|gamma(x)|).  First ln(|gamma(x)|) is computed.  Then,
  1566.    * if exp is true, the exponential of that value is computed, and the sign
  1567.    * is restored.
  1568.    */
  1569.   private static long lgamma(long x, boolean exp) {
  1570.     int hx = getHI(x);
  1571.     int lx = getLO(x);
  1572.     // purge off +-inf, NaN, +-0, and negative arguments 
  1573.     boolean negative = false;
  1574.     int ix = hx&0x7fffffff;
  1575.     if(ix>=0x7ff00000) return mul(x, x); 
  1576.     if((ix|lx)==0) return POSITIVE_INFINITY; // one/zero
  1577.     if(ix<0x3b900000) { // |x|<2**-70, return -log(|x|)
  1578.       if(hx<0) {
  1579.         negative = true;
  1580.         x = negate(x);
  1581.       }
  1582.       x = negate(log(x));
  1583.       if (exp) {
  1584.         x = exp(x);
  1585.         if (negative) {
  1586.           x = negate(x);
  1587.         }
  1588.       }
  1589.       return x;
  1590.     }
  1591.     long t, nadj;
  1592.     if(hx<0) {
  1593.         if(ix>=0x43300000) // |x|>=2**52, must be -integer 
  1594.             return POSITIVE_INFINITY; // one/zero;
  1595.         t = sinPi(x);
  1596.         if(isZero(t)) return POSITIVE_INFINITY; // one/zero; // -integer 
  1597.         nadj = log(div(PI, abs(mul(t, x))));
  1598.         if (lt(t, ZERO)) {
  1599.           negative = true;
  1600.         }
  1601.         x = negate(x);
  1602.     } else {
  1603.       nadj = ZERO;
  1604.     }
  1605.     // purge off 1 and 2 
  1606.     long r, y;
  1607.     int i;
  1608.     if((((ix-0x3ff00000)|lx)==0)||(((ix-0x40000000)|lx)==0)) r = ZERO;
  1609.     // for x < 2.0 
  1610.     else if(ix<0x40000000) {
  1611.       if(ix<=0x3feccccc) { // lgamma(x) = lgamma(x+1)-log(x) 
  1612.         r = negate(log(x));
  1613.         if(ix>=0x3FE76944) {
  1614.           y = sub(ONE, x); 
  1615.           i=0;
  1616.         } else if(ix>=0x3FCDA661) {
  1617.           y= sub(x, sub(TC, ONE)); 
  1618.           i=1;
  1619.         } else {
  1620.           y = x; 
  1621.           i=2;
  1622.         }
  1623.       } else {
  1624.         r = ZERO;
  1625.         if(ix>=0x3FFBB4C3) {
  1626.           y=sub(TWO, x);
  1627.           i=0;
  1628.         } // [1.7316,2]
  1629.         else if(ix>=0x3FF3B4C4) {
  1630.           y=sub(x, TC);
  1631.           i=1;
  1632.         } // [1.23,1.73] 
  1633.         else {
  1634.           y=sub(x, ONE);
  1635.           i=2;
  1636.         }
  1637.       }
  1638.       long w, z, p1, p2, p3, p;
  1639.       switch(i) {
  1640.         case 0:
  1641.           z = mul(y, y);
  1642.           p1 = add(A0, mul(z, add(A2, mul(z, add(A4, mul(
  1643.                   z, add(A6, mul(z, add(A8, mul(z, A10))))))))));
  1644.           p2 = mul(z, add(A1, mul(z, add(A3, mul(z, add(
  1645.                   A5, mul(z, add(A7, mul(z, add(A9, mul(z, A11)))))))))));
  1646.           p = add(mul(y, p1), p2);
  1647.           r = add(r, sub(p, scalbn(y, -1))); 
  1648.           break;
  1649.         case 1:
  1650.           z = mul(y, y);
  1651.           w = mul(z, y);
  1652.           p1 = add(TB0, mul(w, add(TB3, mul(w, add(TB6, mul(w,
  1653.                   add(TB9, mul(w, TB12)))))))); // parallel comp 
  1654.           p2 = add(TB1, mul(w, add(TB4, mul(w, add(TB7, mul(w,
  1655.                   add(TB10, mul(w, TB13))))))));
  1656.           p3 = add(TB2, mul(w, add(TB5, mul(w, add(TB8, mul(w,
  1657.                   add(TB11, mul(w, TB14))))))));
  1658.           p = sub(mul(z, p1), sub(TT, mul(w, add(p2, 
  1659.                   mul(y, p3)))));
  1660.           r = add(r, add(TF, p));
  1661.           break;
  1662.         case 2:
  1663.           p1 = mul(y, add(U0, mul(y, add(U1, mul(y, add(U2,
  1664.                   mul(y, add(U3, mul(y, add(U4, mul(y, U5)))))))))));
  1665.           p2 = add(ONE, mul(y, add(V1, mul(y, add(V2, mul(y,
  1666.                   add(V3, mul(y, add(V4, mul(y, V5))))))))));
  1667.           r = add(r, add(negate(scalbn(y, -1)), div(p1, p2)));
  1668.       }
  1669.     }
  1670.     else if(ix<0x40200000) { // x < 8.0 
  1671.       i = intValue(x);
  1672.       t = ZERO;
  1673.       y = sub(x, intToDouble(i));
  1674.       long p = mul(y, add(SB0, mul(y, add(SB1, mul(y, add(SB2, 
  1675.               mul(y, add(SB3, mul(y, add(SB4, mul(y, add(SB5,
  1676.               mul(y, SB6)))))))))))));
  1677.       long q = add(ONE, mul(y, add(R1, mul(y, add(R2, mul(y, add(R3,
  1678.               mul(y, add(R4, mul(y, add(R5, mul(y, R6))))))))))));
  1679.       r = add(scalbn(y, -1), div(p, q));
  1680.       long z = ONE; // lgamma(1+s) = log(s) + lgamma(s) 
  1681.       switch(i) {
  1682.         case 7: z = mul(z, add(y, SIX)); // FALLTHRU 
  1683.         case 6: z = mul(z, add(y, FIVE)); // FALLTHRU 
  1684.         case 5: z = mul(z, add(y, FOUR)); // FALLTHRU 
  1685.         case 4: z = mul(z, add(y, THREE)); // FALLTHRU 
  1686.         case 3: z = mul(z, add(y, TWO)); // FALLTHRU 
  1687.                 r = add(r, log(z)); 
  1688.                 break;
  1689.         }
  1690.     // 8.0 <= x < 2**58 
  1691.     } else if (ix < 0x43900000) {
  1692.         t = log(x);
  1693.         long z = div(ONE, x);
  1694.         y = mul(z, z);
  1695.         long w = add(W0, mul(z, add(W1, mul(y, add(W2, mul(y, 
  1696.                 add(W3, mul(y, add(W4, mul(y, add(W5, mul(y, 
  1697.                 W6))))))))))));
  1698.         r = add(mul(sub(x, ONE_HALF), sub(t, ONE)), w);
  1699.     } else {
  1700.     // 2**58 <= x <= inf 
  1701.       r = mul(x, sub(log(x), ONE));
  1702.     }
  1703.     if(hx<0) r = sub(nadj, r);
  1704.     if (exp) {
  1705.       r = exp(r);
  1706.       if (negative) {
  1707.         r = negate(r);
  1708.       }
  1709.     }
  1710.     return r;
  1711.   }
  1712.  
  1713.   private static final long TWO52 = 0x4330000000000000L; // 4.50359962737049600000e+15
  1714.   /** used by lgamma */
  1715.   private static long sinPi(long x) {
  1716.     int ix = 0x7fffffff & getHI(x);
  1717.     if(ix<0x3fd00000) return kernelSin(mul(PI, x), ZERO, 0);
  1718.     long y = negate(x); // x is assume negative
  1719.     // argument reduction, make sure inexact flag not raised if input is 
  1720.     // an integer
  1721.     long z = floor(y);
  1722.     int n;
  1723.     if (ne(z, y)) { // inexact anyway
  1724.       y = scalbn(y, -1);
  1725.       y = scalbn(sub(y, floor(y)), 1); // y = |x| mod 2.0
  1726.       n = intValue(scalbn(y, 2));
  1727.     } else {
  1728.       if(ix>=0x43400000) {
  1729.         y = ZERO; n = 0; // y must be even
  1730.       } else {
  1731.         if(ix<0x43300000) z = add(y, TWO52); // exact
  1732.         n = getLO(z) & 1; // lower word of z 
  1733.         y = intToDouble(n);
  1734.         n <<= 2;
  1735.       }
  1736.     }
  1737.     switch (n) {
  1738.       case 0:   y =  kernelSin(mul(PI, y),ZERO,0); break;
  1739.       case 1:   
  1740.       case 2:   y =  kernelCos(mul(PI, sub(ONE_HALF, y)),ZERO); break;
  1741.       case 3:  
  1742.       case 4:   y =  kernelSin(mul(PI, sub(ONE, y)),ZERO,0); break;
  1743.       case 5:
  1744.       case 6:   y = negate(kernelCos(mul(PI, sub(y, THREE_HALVES)),ZERO)); break;
  1745.       default:  y =  kernelSin(mul(PI, sub(y, TWO)),ZERO,0); break;
  1746.     }
  1747.     return negate(y);
  1748.   }
  1749.      
  1750.   
  1751.   /////////////////////////////////////////////////////////////////////////////
  1752.   // Instance members
  1753.   /////////////////////////////////////////////////////////////////////////////
  1754.   private final long value;
  1755.   
  1756.   /////////////////////////////////////////////////////////////////////////////
  1757.   // Constructors
  1758.   /////////////////////////////////////////////////////////////////////////////
  1759.   /**
  1760.    * Constructs a newly-allocated <code>MicroDouble</code> object that represents 
  1761.    * the argument. 
  1762.    *
  1763.    * @param d the <code>double</code> value to be represented by the <code>MicroDouble</code>.
  1764.    */
  1765.   public MicroDouble(long d) {
  1766.     // canonicalize NaN values so that hashCode() and equals() can be simpler
  1767.     if (isNaN(d)) {
  1768.       d = NaN;
  1769.     }
  1770.     value = d;
  1771.   }
  1772.   
  1773.   /**
  1774.    * Constructs a newly-allocated <code>MicroDouble</code> object that represents 
  1775.    * the argument.
  1776.    *
  1777.    * @param s a <code>String</code> to be converted to a <code>MicroDouble</code>.
  1778.    * @throws NumberFormatException if the <code>String</code> does not contain a
  1779.    *         parsable number.
  1780.    * @see #parseDouble(String)
  1781.    */
  1782.   public MicroDouble(String s) {
  1783.     this(parseDouble(s));
  1784.   }
  1785.   
  1786.   /////////////////////////////////////////////////////////////////////////////
  1787.   // Instance methods
  1788.   /////////////////////////////////////////////////////////////////////////////
  1789.   /**
  1790.    * Returns the <code>double</code> value of this <code>MicroDouble</code>
  1791.    * object.
  1792.    */
  1793.   public long doubleValue() {
  1794.     return value;
  1795.   }
  1796.   /**
  1797.    * Returns a String object representing this MicroDouble's value.
  1798.    * Equivalent to <code>toString(doubleValue())</code>.
  1799.    *
  1800.    * @see #toString(long)
  1801.    */
  1802.   public String toString() {
  1803.     return toString(value);
  1804.   }
  1805.     
  1806.   /**
  1807.    * Returns a hash code for this <code>MicroDouble</code> object.
  1808.    * Equivalent to <code>(int) (doubleValue() ^ (doubleValue >>> 32))</code>
  1809.    */
  1810.   public int hashCode() {
  1811.     return ((int) value) ^ ((int) (value >>> 32));
  1812.   }
  1813.   
  1814.   /**
  1815.    * Compares this object against the specified object.
  1816.    * Equivalent to 
  1817.    * <code>((obj instanceof MicroDouble) && (compare(((MicroDouble) obj).doubleValue(), doubleValue()) == 0))</code>
  1818.    * 
  1819.    * @see #compare(long, long)
  1820.    */
  1821.   public boolean equals(Object obj) {
  1822.     return ((obj instanceof MicroDouble) 
  1823.             && (((MicroDouble) obj).value == value));
  1824.   }
  1825.   
  1826. }