double powi(x, nn) double x; int nn;
{ int n, e, sign, asign, lx; double w, y, s;
/* See pow.c for these tests. */ if (x == 0.0) { if (nn == 0) return (1.0); elseif (nn < 0) return (INFINITY); else { if (nn & 1) return (x); else return (0.0);
}
}
if (nn == 0) return (1.0);
if (nn == -1) return (1.0 / x);
if (x < 0.0) {
asign = -1;
x = -x;
} else
asign = 0;
if (nn < 0) {
sign = -1;
n = -nn;
} else {
sign = 1;
n = nn;
}
/* Even power will be positive. */ if ((n & 1) == 0)
asign = 0;
/* Overflow detection */
/* Calculate approximate logarithm of answer */
s = frexp(x, &lx);
e = (lx - 1) * n; if ((e == 0) || (e > 64) || (e < -64)) {
s = (s - 7.0710678118654752e-1) / (s + 7.0710678118654752e-1);
s = (2.9142135623730950 * s - 0.5 + lx) * nn * LOGE2;
} else {
s = LOGE2 * e;
}
if (s > MAXLOG) {
mtherr("powi", OVERFLOW);
y = INFINITY; goto done;
}
#if DENORMAL if (s < MINLOG) {
y = 0.0; goto done;
}
/* Handle tiny denormal answer, but with less accuracy *sinceroundofferrorin1.0/xwillbeamplified. *Theprecisedemarcationshouldbethegradualunderflowthreshold.
*/ if ((s < (-MAXLOG + 2.0)) && (sign < 0)) {
x = 1.0 / x;
sign = -sign;
} #else /* do not produce denormal answer */ if (s < -MAXLOG) return (0.0); #endif
/* First bit of the power */ if (n & 1)
y = x;
else
y = 1.0;
w = x;
n >>= 1; while (n) {
w = w * w; /* arg to the 2-to-the-kth power */ if (n & 1) /* if that bit is set, then include in product */
y *= w;
n >>= 1;
}
if (sign < 0)
y = 1.0 / y;
done:
if (asign) { /* odd power of negative number */ if (y == 0.0)
y = NEGZERO; else
y = -y;
} return (y);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.