/* log2l.c
*
* Base 2 logarithm , long double precision
*
*
*
* SYNOPSIS :
*
* long double x , y , log2l ( ) ;
*
* y = log2l ( x ) ;
*
*
*
* DESCRIPTION :
*
* Returns the base 2 logarithm of x .
*
* The argument is separated into its exponent and fractional
* parts . If the exponent is between - 1 and + 1 , the ( natural )
* logarithm of the fraction is approximated by
*
* log ( 1 + x ) = x - 0 . 5 x * * 2 + x * * 3 P ( x ) / Q ( x ) .
*
* Otherwise , setting z = 2 ( x - 1 ) / x + 1 ) ,
*
* log ( x ) = z + z * * 3 P ( z ) / Q ( z ) .
*
*
*
* ACCURACY :
*
* Relative error :
* arithmetic domain # trials peak rms
* IEEE 0 . 5 , 2 . 0 30000 9 . 8 e - 20 2 . 7 e - 20
* IEEE exp ( + - 10000 ) 70000 5 . 4 e - 20 2 . 3 e - 20
*
* In the tests over the interval exp ( + - 10000 ) , the logarithms
* of the random arguments were uniformly distributed over
* [ - 10000 , + 10000 ] .
*
* ERROR MESSAGES :
*
* log singularity : x = 0 ; returns - INFINITYL
* log domain : x < 0 ; returns NANL
*/
/*
Cephes Math Library Release 2 . 8 : May , 1998
Copyright 1984 , 1991 , 1998 by Stephen L . Moshier
*/
#include "mconf.h"
/* Coefficients for ln(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
* 1 / sqrt ( 2 ) < = x < sqrt ( 2 )
* Theoretical peak relative error = 6 . 2 e - 22
*/
#ifdef UNK
static long double P[] = {
4 .9962495940332550844739 E-1 L,
1 .0767376367209449010438 E1L,
7 .7671073698359539859595 E1L,
2 .5620629828144409632571 E2L,
4 .2401812743503691187826 E2L,
3 .4258224542413922935104 E2L,
1 .0747524399916215149070 E2L,
};
static long double Q[] = {
/* 1.0000000000000000000000E0,*/
2 .3479774160285863271658 E1L,
1 .9444210022760132894510 E2L,
7 .7952888181207260646090 E2L,
1 .6911722418503949084863 E3L,
2 .0307734695595183428202 E3L,
1 .2695660352705325274404 E3L,
3 .2242573199748645407652 E2L,
};
#endif
#ifdef IBMPC
static short P[] = {
0 xfe72,0 xce22,0 xd7b9,0 xffce,0 x3ffd, XPD
0 xb778,0 x0e34,0 x2c71,0 xac47,0 x4002, XPD
0 xea8b,0 xc751,0 x96f8,0 x9b57,0 x4005, XPD
0 xfeaf,0 x6a02,0 x67fb,0 x801a,0 x4007, XPD
0 x6b5a,0 xf252,0 x51ff,0 xd402,0 x4007, XPD
0 x39ce,0 x9f76,0 x8704,0 xab4a,0 x4007, XPD
0 x1b39,0 x740b,0 x532e,0 xd6f3,0 x4005, XPD
};
static short Q[] = {
/*0x0000,0x0000,0x0000,0x8000,0x3fff,*/
0 x2f3a,0 xbf26,0 x93d5,0 xbbd6,0 x4003, XPD
0 x13c8,0 x031a,0 x2d7b,0 xc271,0 x4006, XPD
0 x449d,0 x1993,0 xd933,0 xc2e1,0 x4008, XPD
0 x5b65,0 x574e,0 x8301,0 xd365,0 x4009, XPD
0 xa65d,0 x3bd2,0 xc043,0 xfdd8,0 x4009, XPD
0 x3b21,0 xffea,0 x1cf5,0 x9eb2,0 x4009, XPD
0 x545c,0 xd708,0 x7e62,0 xa136,0 x4007, XPD
};
#endif
#ifdef MIEEE
static long P[] = {
0 x3ffd0000,0 xffced7b9,0 xce22fe72,
0 x40020000,0 xac472c71,0 x0e34b778,
0 x40050000,0 x9b5796f8,0 xc751ea8b,
0 x40070000,0 x801a67fb,0 x6a02feaf,
0 x40070000,0 xd40251ff,0 xf2526b5a,
0 x40070000,0 xab4a8704,0 x9f7639ce,
0 x40050000,0 xd6f3532e,0 x740b1b39,
};
static long Q[] = {
/*0x3fff0000,0x80000000,0x00000000,*/
0 x40030000,0 xbbd693d5,0 xbf262f3a,
0 x40060000,0 xc2712d7b,0 x031a13c8,
0 x40080000,0 xc2e1d933,0 x1993449d,
0 x40090000,0 xd3658301,0 x574e5b65,
0 x40090000,0 xfdd8c043,0 x3bd2a65d,
0 x40090000,0 x9eb21cf5,0 xffea3b21,
0 x40070000,0 xa1367e62,0 xd708545c,
};
#endif
/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
* where z = 2 ( x - 1 ) / ( x + 1 )
* 1 / sqrt ( 2 ) < = x < sqrt ( 2 )
* Theoretical peak relative error = 6 . 16 e - 22
*/
#ifdef UNK
static long double R[4 ] = {
1 .9757429581415468984296 E-3 L,
-7 .1990767473014147232598 E-1 L,
1 .0777257190312272158094 E1L,
-3 .5717684488096787370998 E1L,
};
static long double S[4 ] = {
/* 1.00000000000000000000E0L,*/
-2 .6201045551331104417768 E1L,
1 .9361891836232102174846 E2L,
-4 .2861221385716144629696 E2L,
};
/* log2(e) - 1 */
#define LOG2EA 4 .4269504088896340735992 e-1 L
#endif
#ifdef IBMPC
static short R[] = {
0 x6ef4,0 xf922,0 x7763,0 x817b,0 x3ff6, XPD
0 x15fd,0 x1af9,0 xde8f,0 xb84b,0 xbffe, XPD
0 x8b96,0 x4f8d,0 xa53c,0 xac6f,0 x4002, XPD
0 x8932,0 xb4e3,0 xe8ae,0 x8ede,0 xc004, XPD
};
static short S[] = {
/*0x0000,0x0000,0x0000,0x8000,0x3fff,*/
0 x7ce4,0 x1fc9,0 xbdc5,0 xd19b,0 xc003, XPD
0 x0af3,0 x0d10,0 x716f,0 xc19e,0 x4006, XPD
0 x4d7d,0 x0f55,0 x5d06,0 xd64e,0 xc007, XPD
};
static short LG2EA[] = {0 xc2ef,0 x705f,0 xeca5,0 xe2a8,0 x3ffd, XPD};
#define LOG2EA *(long double *)LG2EA
#endif
#ifdef MIEEE
static long R[12 ] = {
0 x3ff60000,0 x817b7763,0 xf9226ef4,
0 xbffe0000,0 xb84bde8f,0 x1af915fd,
0 x40020000,0 xac6fa53c,0 x4f8d8b96,
0 xc0040000,0 x8edee8ae,0 xb4e38932,
};
static long S[9 ] = {
/*0x3fff0000,0x80000000,0x00000000,*/
0 xc0030000,0 xd19bbdc5,0 x1fc97ce4,
0 x40060000,0 xc19e716f,0 x0d100af3,
0 xc0070000,0 xd64e5d06,0 x0f554d7d,
};
static long LG2EA[] = {0 x3ffd0000,0 xe2a8eca5,0 x705fc2ef};
#define LOG2EA *(long double *)LG2EA
#endif
#define SQRTH 0 .70710678118654752440 L
extern long double MINLOGL;
#ifdef ANSIPROT
extern long double frexpl ( long double , int * );
extern long double ldexpl ( long double , int );
extern long double polevll ( long double , void *, int );
extern long double p1evll ( long double , void *, int );
extern int isnanl ( long double );
#else
long double frexpl(), ldexpl(), polevll(), p1evll();
extern int isnanl ();
#endif
#ifdef INFINITIES
extern long double INFINITYL;
#endif
#ifdef NANS
extern long double NANL;
#endif
long double log2l(x)
long double x;
{
VOLATILE long double z;
long double y;
int e;
#ifdef NANS
if ( isnanl(x) )
return (x);
#endif
#ifdef INFINITIES
if ( x == INFINITYL )
return (x);
#endif
/* Test for domain */
if ( x <= 0 .0 L )
{
if ( x == 0 .0 L )
{
#ifdef INFINITIES
return ( -INFINITYL );
#else
mtherr( "log2l" , SING );
return ( -16384 .0 L );
#endif
}
else
{
#ifdef NANS
return ( NANL );
#else
mtherr( "log2l" , DOMAIN );
return ( -16384 .0 L );
#endif
}
}
/* separate mantissa from exponent */
/* Note, frexp is used so that denormal numbers
* will be handled properly .
*/
x = frexpl( x, &e );
/* logarithm using log(x) = z + z**3 P(z)/Q(z),
* where z = 2 ( x - 1 ) / x + 1 )
*/
if ( (e > 2 ) || (e < -2 ) )
{
if ( x < SQRTH )
{ /* 2( 2x-1 )/( 2x+1 ) */
e -= 1 ;
z = x - 0 .5 L;
y = 0 .5 L * z + 0 .5 L;
}
else
{ /* 2 (x-1)/(x+1) */
z = x - 0 .5 L;
z -= 0 .5 L;
y = 0 .5 L * x + 0 .5 L;
}
x = z / y;
z = x*x;
y = x * ( z * polevll( z, R, 3 ) / p1evll( z, S, 3 ) );
goto done;
}
/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
if ( x < SQRTH )
{
e -= 1 ;
x = ldexpl( x, 1 ) - 1 .0 L; /* 2x - 1 */
}
else
{
x = x - 1 .0 L;
}
z = x*x;
y = x * ( z * polevll( x, P, 6 ) / p1evll( x, Q, 7 ) );
y = y - ldexpl( z, -1 ); /* -0.5x^2 + ... */
done:
/* Multiply log of fraction by log2(e)
* and base 2 exponent by 1
*
* * * * CAUTION * * *
*
* This sequence of operations is critical and it may
* be horribly defeated by some compiler optimizers .
*/
z = y * LOG2EA;
z += x * LOG2EA;
z += y;
z += x;
z += e;
return ( z );
}
Messung V0.5 in Prozent C=94 H=99 G=96
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-14)
¤
*© Formatika GbR, Deutschland