/*
* Copyright ( c ) 1998 , 2022 , Oracle and / or its affiliates . All rights reserved .
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER .
*
* This code is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 only , as
* published by the Free Software Foundation . Oracle designates this
* particular file as subject to the " Classpath " exception as provided
* by Oracle in the LICENSE file that accompanied this code .
*
* This code is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License
* version 2 for more details ( a copy is included in the LICENSE file that
* accompanied this code ) .
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work ; if not , write to the Free Software Foundation ,
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA .
*
* Please contact Oracle , 500 Oracle Parkway , Redwood Shores , CA 94065 USA
* or visit www . oracle . com if you need additional information or have any
* questions .
*/
/* __ieee754_log(x)
* Return the logarithm of x
*
* Method :
* 1 . Argument Reduction : find k and f such that
* x = 2 ^ k * ( 1 + f ) ,
* where sqrt ( 2 ) / 2 < 1 + f < sqrt ( 2 ) .
*
* 2 . Approximation of log ( 1 + f ) .
* Let s = f / ( 2 + f ) ; based on log ( 1 + f ) = log ( 1 + s ) - log ( 1 - s )
* = 2 s + 2 / 3 s * * 3 + 2 / 5 s * * 5 + . . . . . ,
* = 2 s + s * R
* We use a special Reme algorithm on [ 0 , 0 . 1716 ] to generate
* a polynomial of degree 14 to approximate R The maximum error
* of this polynomial approximation is bounded by 2 * * - 58 . 45 . In
* other words ,
* 2 4 6 8 10 12 14
* R ( z ) ~ Lg1 * s + Lg2 * s + Lg3 * s + Lg4 * s + Lg5 * s + Lg6 * s + Lg7 * s
* ( the values of Lg1 to Lg7 are listed in the program )
* and
* | 2 14 | - 58 . 45
* | Lg1 * s + . . . + Lg7 * s - R ( z ) | < = 2
* | |
* Note that 2 s = f - s * f = f - hfsq + s * hfsq , where hfsq = f * f / 2 .
* In order to guarantee error in log below 1 ulp , we compute log
* by
* log ( 1 + f ) = f - s * ( f - R ) ( if f is not too large )
* log ( 1 + f ) = f - ( hfsq - s * ( hfsq + R ) ) . ( better accuracy )
*
* 3 . Finally , log ( x ) = k * ln2 + log ( 1 + f ) .
* = k * ln2_hi + ( f - ( hfsq - ( s * ( hfsq + R ) + k * ln2_lo ) ) )
* Here ln2 is split into two floating point number :
* ln2_hi + ln2_lo ,
* where n * ln2_hi is always exact for | n | < 2000 .
*
* Special cases :
* log ( x ) is NaN with signal if x < 0 ( including - INF ) ;
* log ( + INF ) is + INF ; log ( 0 ) is - INF with signal ;
* log ( NaN ) is that NaN with no signal .
*
* Accuracy :
* according to an error analysis , the error is always less than
* 1 ulp ( unit in the last place ) .
*
* Constants :
* The hexadecimal values are the intended ones for the following
* constants . The decimal values may be used , provided that the
* compiler will convert from decimal to binary accurately enough
* to produce the hexadecimal values shown .
*/
#include "fdlibm.h"
#ifdef __STDC__
static const double
#else
static double
#endif
ln2_hi = 6 .93147180369123816490 e-01 , /* 3fe62e42 fee00000 */
ln2_lo = 1 .90821492927058770002 e-10 , /* 3dea39ef 35793c76 */
two54 = 1 .80143985094819840000 e+16 , /* 43500000 00000000 */
Lg1 = 6 .666666666666735130 e-01 , /* 3FE55555 55555593 */
Lg2 = 3 .999999999940941908 e-01 , /* 3FD99999 9997FA04 */
Lg3 = 2 .857142874366239149 e-01 , /* 3FD24924 94229359 */
Lg4 = 2 .222219843214978396 e-01 , /* 3FCC71C5 1D8E78AF */
Lg5 = 1 .818357216161805012 e-01 , /* 3FC74664 96CB03DE */
Lg6 = 1 .531383769920937332 e-01 , /* 3FC39A09 D078C69F */
Lg7 = 1 .479819860511658591 e-01 ; /* 3FC2F112 DF3E5244 */
static double zero = 0 .0 ;
#ifdef __STDC__
double __ieee754_log(double x)
#else
double __ieee754_log(x)
double x;
#endif
{
double hfsq,f,s,z,R,w,t1,t2,dk;
int k,hx,i,j;
unsigned lx;
hx = __HI(x); /* high word of x */
lx = __LO(x); /* low word of x */
k=0 ;
if (hx < 0 x00100000) { /* x < 2**-1022 */
if (((hx&0 x7fffffff)|lx)==0 )
return -two54/zero; /* log(+-0)=-inf */
if (hx<0 ) return (x-x)/zero; /* log(-#) = NaN */
k -= 54 ; x *= two54; /* subnormal number, scale up x */
hx = __HI(x); /* high word of x */
}
if (hx >= 0 x7ff00000) return x+x;
k += (hx>>20 )-1023 ;
hx &= 0 x000fffff;
i = (hx+0 x95f64)&0 x100000;
__HI(x) = hx|(i^0 x3ff00000); /* normalize x or x/2 */
k += (i>>20 );
f = x-1 .0 ;
if ((0 x000fffff&(2 +hx))<3 ) { /* |f| < 2**-20 */
if (f==zero) {
if (k==0 ) return zero;
else {dk=(double )k; return dk*ln2_hi+dk*ln2_lo;}
}
R = f*f*(0 .5 -0 .33333333333333333 *f);
if (k==0 ) return f-R; else {dk=(double )k;
return dk*ln2_hi-((R-dk*ln2_lo)-f);}
}
s = f/(2 .0 +f);
dk = (double )k;
z = s*s;
i = hx-0 x6147a;
w = z*z;
j = 0 x6b851-hx;
t1= w*(Lg2+w*(Lg4+w*Lg6));
t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
i |= j;
R = t2+t1;
if (i>0 ) {
hfsq=0 .5 *f*f;
if (k==0 ) return f-(hfsq-s*(hfsq+R)); else
return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f);
} else {
if (k==0 ) return f-s*(f-R); else
return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f);
}
}
Messung V0.5 in Prozent C=87 H=100 G=93
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-09-30)
¤
*Bot Zugriff