/*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG> * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE.
*/
/* * exp2(x): compute the base 2 exponential of x * * Accuracy: Peak error < 0.503 ulp for normalized results. * * Method: (accurate tables) * * Reduce x: * x = 2**k + y, for integer k and |y| <= 1/2. * Thus we have exp2(x) = 2**k * exp2(y). * * Reduce y: * y = i/TBLSIZE + z - eps[i] for integer i near y * TBLSIZE. * Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z - eps[i]), * with |z - eps[i]| <= 2**-9 + 2**-39 for the table used. * * We compute exp2(i/TBLSIZE) via table lookup and exp2(z - eps[i]) via * a degree-5 minimax polynomial with maximum error under 1.3 * 2**-61. * The values in exp2t[] and eps[] are chosen such that * exp2t[i] = exp2(i/TBLSIZE + eps[i]), and eps[i] is a small offset such * that exp2t[i] is accurate to 2**-64. * * Note that the range of i is +-TBLSIZE/2, so we actually index the tables * by i0 = i + TBLSIZE/2. For cache efficiency, exp2t[] and eps[] are * virtual tables, interleaved in the real table tbl[]. * * This method is due to Gal, with many details due to Gal and Bachelis: * * Gal, S. and Bachelis, B. An Accurate Elementary Mathematical Library * for the IEEE Floating Point Standard. TOMS 17(1), 26-46 (1991).
*/ double
exp2(double x)
{ double r, t, twopk, twopkp1000, z;
uint32_t hx, ix, lx, i0; int k;
/* Filter out exceptional cases. */
GET_HIGH_WORD(hx,x);
ix = hx & 0x7fffffff; /* high word of |x| */ if(ix >= 0x40900000) { /* |x| >= 1024 */ if(ix >= 0x7ff00000) {
GET_LOW_WORD(lx,x); if(((ix & 0xfffff) | lx) != 0 || (hx & 0x80000000) == 0) return (x + x); /* x is NaN or +Inf */ else return (0.0); /* x is -Inf */
} if(x >= 0x1.0p10) return (huge * huge); /* overflow */ if(x <= -0x1.0ccp10) return (twom1000 * twom1000); /* underflow */
} elseif (ix < 0x3c900000) { /* |x| < 0x1p-54 */ return (1.0 + x);
}
/* Reduce x, computing z, i0, and k. */
STRICT_ASSIGN(double, t, x + redux);
GET_LOW_WORD(i0, t);
i0 += TBLSIZE / 2;
k = (i0 >> TBLBITS) << 20;
i0 = (i0 & (TBLSIZE - 1)) << 1;
t -= redux;
z = x - t;
/* Compute r = exp2(y) = exp2t[i0] * p(z - eps[i]). */
t = tbl[i0]; /* exp2t[i0] */
z -= tbl[i0 + 1]; /* eps[i0] */ if (k >= -(1021 << 20))
INSERT_WORDS(twopk, 0x3ff00000 + k, 0); else
INSERT_WORDS(twopkp1000, 0x3ff00000 + k + (1000 << 20), 0);
r = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * P5))));
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 ist noch experimentell.