in commons-statistics-inference/src/main/java/org/apache/commons/statistics/inference/DD.java [1172:1205]
static long fastPowScaled(double x, double xx, int n, DD f) {
// Edge cases.
if (n == 0) {
f.set(0.5, 0);
return 1;
}
// IEEE result for non-finite or zero
if (!Double.isFinite(x) || x == 0) {
f.set(Math.pow(x, n), 0);
return 0;
}
// Here the number is non-zero finite
assert x == x + xx : NOT_NOMALIZED;
long b = frexp(x, xx, f);
// Handle exact powers of 2
if (Math.abs(f.hi) == HALF && f.lo == 0) {
// (f * 2^b)^n = (2f)^n * 2^(b-1)^n
// Use Math.pow to create the sign.
// Note the result must be scaled to the fractional representation
// by multiplication by 0.5 and addition of 1 to the exponent.
f.hi = 0.5 * Math.pow(2 * f.hi, n);
// Propagate sign change (x*f.hi) to the zero
f.lo = Math.copySign(0.0, x * f.hi * xx);
return 1 + (b - 1) * n;
}
if (n < 0) {
b = computeFastPowScaled(b, f.hi, f.lo, -n, f);
// Result is a non-zero fraction part so inversion is safe
inverse(f.hi, f.lo, f);
// Rescale to [0.5, 1.0]
return -b + frexp(f.hi, f.lo, f);
}
return computeFastPowScaled(b, f.hi, f.lo, n, f);
}