/* @(#)e_log.c 1.3 95/01/18 */
/*
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
* Copyright ( C ) 1993 by Sun Microsystems , Inc . All rights reserved .
*
* Developed at SunSoft , a Sun Microsystems , Inc . business .
* Permission to use , copy , modify , and distribute this
* software is freely granted , provided that this notice
* is preserved .
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
//#include <sys/cdefs.h>
//__FBSDID("$FreeBSD$");
/*
* k_log1p ( f ) :
* Return log ( 1 + f ) - f for 1 + f in ~ [ sqrt ( 2 ) / 2 , sqrt ( 2 ) ] .
*
* The following describes the overall strategy for computing
* logarithms in base e . The argument reduction and adding the final
* term of the polynomial are done by the caller for increased accuracy
* when different bases are used .
*
* 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 .
*/
static const double
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 */
/*
* We always inline k_log1p ( ) , since doing so produces a
* substantial performance improvement ( ~ 40 % on amd64 ) .
*/
static inline double
k_log1p(double f)
{
double hfsq,s,z,R,w,t1,t2;
s = f/(2 .0 +f);
z = s*s;
w = z*z;
t1= w*(Lg2+w*(Lg4+w*Lg6));
t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
R = t2+t1;
hfsq=0 .5 *f*f;
return s*(hfsq+R);
}
Messung V0.5 in Prozent C=88 H=100 G=94
¤ Dauer der Verarbeitung: 0.16 Sekunden
(vorverarbeitet am 2026-08-24)
¤
*© Formatika GbR, Deutschland