/*-
* 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 .
*/
//#include <sys/cdefs.h>
//__FBSDID("$FreeBSD$");
#include <float .h>
#include "math_private.h"
#define TBLBITS 4
#define TBLSIZE (1 << TBLBITS)
static const float
redux = 0 x1.8 p23f / TBLSIZE,
P1 = 0 x1.62 e430p-1 f,
P2 = 0 x1.ebfbe0p-3 f,
P3 = 0 x1.c6b348p-5 f,
P4 = 0 x1.3 b2c9cp-7 f;
static volatile float
huge = 0 x1p100f,
twom100 = 0 x1p-100 f;
static const double exp2ft[TBLSIZE] = {
0 x1.6 a09e667f3bcdp-1 ,
0 x1.7 a11473eb0187p-1 ,
0 x1.8 ace5422aa0dbp-1 ,
0 x1.9 c49182a3f090p-1 ,
0 x1.ae89f995ad3adp-1 ,
0 x1.c199bdd85529cp-1 ,
0 x1.d5818dcfba487p-1 ,
0 x1.ea4afa2a490dap-1 ,
0 x1.0000000000000 p+0 ,
0 x1.0 b5586cf9890fp+0 ,
0 x1.172 b83c7d517bp+0 ,
0 x1.2387 a6e756238p+0 ,
0 x1.306 fe0a31b715p+0 ,
0 x1.3 dea64c123422p+0 ,
0 x1.4 bfdad5362a27p+0 ,
0 x1.5 ab07dd485429p+0 ,
};
/*
* exp2f ( x ) : compute the base 2 exponential of x
*
* Accuracy : Peak error < 0 . 501 ulp ; location of peak : - 0 . 030110927 .
*
* Method : ( equally - spaced tables )
*
* Reduce x :
* x = 2 * * k + y , for integer k and | y | < = 1 / 2 .
* Thus we have exp2f ( x ) = 2 * * k * exp2 ( y ) .
*
* Reduce y :
* y = i / TBLSIZE + z for integer i near y * TBLSIZE .
* Thus we have exp2 ( y ) = exp2 ( i / TBLSIZE ) * exp2 ( z ) ,
* with | z | < = 2 * * - ( TBLSIZE + 1 ) .
*
* We compute exp2 ( i / TBLSIZE ) via table lookup and exp2 ( z ) via a
* degree - 4 minimax polynomial with maximum error under 1 . 4 * 2 * * - 33 .
* Using double precision for everything except the reduction makes
* roundoff error insignificant and simplifies the scaling step .
*
* This method is due to Tang , but I do not use his suggested parameters :
*
* Tang , P . Table - driven Implementation of the Exponential Function
* in IEEE Floating - Point Arithmetic . TOMS 15 ( 2 ) , 144 - 157 ( 1989 ) .
*/
float
exp2f(float x)
{
double tv, twopk, u, z;
float t;
uint32_t hx, ix, i0;
int32_t k;
/* Filter out exceptional cases. */
GET_FLOAT_WORD(hx, x);
ix = hx & 0 x7fffffff; /* high word of |x| */
if (ix >= 0 x43000000) { /* |x| >= 128 */
if (ix >= 0 x7f800000) {
if ((ix & 0 x7fffff) != 0 || (hx & 0 x80000000) == 0 )
return (x + x); /* x is NaN or +Inf */
else
return (0 .0 ); /* x is -Inf */
}
if (x >= 0 x1.0 p7f)
return (huge * huge); /* overflow */
if (x <= -0 x1.2 cp7f)
return (twom100 * twom100); /* underflow */
} else if (ix <= 0 x33000000) { /* |x| <= 0x1p-25 */
return (1 .0 f + x);
}
/* Reduce x, computing z, i0, and k. */
STRICT_ASSIGN(float , t, x + redux);
GET_FLOAT_WORD(i0, t);
i0 += TBLSIZE / 2 ;
k = (i0 >> TBLBITS) << 20 ;
i0 &= TBLSIZE - 1 ;
t -= redux;
z = x - t;
INSERT_WORDS(twopk, 0 x3ff00000 + k, 0 );
/* Compute r = exp2(y) = exp2ft[i0] * p(z). */
tv = exp2ft[i0];
u = tv * z;
tv = tv + u * (P1 + z * P2) + u * (z * z) * (P3 + z * P4);
/* Scale by 2**(k>>20). */
return (tv * twopk);
}
Messung V0.5 in Prozent C=90 H=100 G=95
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-08-24)
¤
*© Formatika GbR, Deutschland