/** * Computes the value of this number raised to an integral power. Follows semantics of Java * Math.pow as closely as possible. * * @param exp the integer exponent * @return x raised to the integral power exp */ public WB_DoubleDouble pow(final int exp) { if (exp == 0.0) { return valueOf(1.0); } WB_DoubleDouble r = new WB_DoubleDouble(this); WB_DoubleDouble s = valueOf(1.0); int n = Math.abs(exp); if (n > 1) { /* Use binary exponentiation */ while (n > 0) { if ((n % 2) == 1) { s.selfMultiply(r); } n /= 2; if (n > 0) { r = r.sqr(); } } } else { s = r; } /* Compute the reciprocal if n is negative. */ if (exp < 0) { return s.reciprocal(); } return s; }
/** * Computes the positive square root of this value. If the number is NaN or negative, NaN is * returned. * * @return the positive square root of this number. If the argument is NaN or less than zero, the * result is NaN. */ public WB_DoubleDouble sqrt() { /* * Strategy: Use Karp's trick: if x is an approximation to sqrt(a), then * * sqrt(a) = a*x + [a - (a*x)^2] * x / 2 (approx) * * The approximation is accurate to twice the accuracy of x. Also, the * multiplication (a*x) and [-]*x can be done with only half the * precision. */ if (isZero()) { return valueOf(0.0); } if (isNegative()) { return NaN; } final double x = 1.0 / Math.sqrt(hi); final double ax = hi * x; final WB_DoubleDouble axdd = valueOf(ax); final WB_DoubleDouble diffSq = this.subtract(axdd.sqr()); final double d2 = diffSq.hi * (x * 0.5); return axdd.add(d2); }