xref: /aosp_15_r20/external/fdlibm/e_log10.c (revision 1e651e1ef2b613db2c4b29ae59c1de74cf0222ae)
1*1e651e1eSRoland Levillain 
2*1e651e1eSRoland Levillain /* @(#)e_log10.c 1.3 95/01/18 */
3*1e651e1eSRoland Levillain /*
4*1e651e1eSRoland Levillain  * ====================================================
5*1e651e1eSRoland Levillain  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6*1e651e1eSRoland Levillain  *
7*1e651e1eSRoland Levillain  * Developed at SunSoft, a Sun Microsystems, Inc. business.
8*1e651e1eSRoland Levillain  * Permission to use, copy, modify, and distribute this
9*1e651e1eSRoland Levillain  * software is freely granted, provided that this notice
10*1e651e1eSRoland Levillain  * is preserved.
11*1e651e1eSRoland Levillain  * ====================================================
12*1e651e1eSRoland Levillain  */
13*1e651e1eSRoland Levillain 
14*1e651e1eSRoland Levillain /* __ieee754_log10(x)
15*1e651e1eSRoland Levillain  * Return the base 10 logarithm of x
16*1e651e1eSRoland Levillain  *
17*1e651e1eSRoland Levillain  * Method :
18*1e651e1eSRoland Levillain  *	Let log10_2hi = leading 40 bits of ieee_log10(2) and
19*1e651e1eSRoland Levillain  *	    log10_2lo = ieee_log10(2) - log10_2hi,
20*1e651e1eSRoland Levillain  *	    ivln10   = 1/ieee_log(10) rounded.
21*1e651e1eSRoland Levillain  *	Then
22*1e651e1eSRoland Levillain  *		n = ieee_ilogb(x),
23*1e651e1eSRoland Levillain  *		if(n<0)  n = n+1;
24*1e651e1eSRoland Levillain  *		x = ieee_scalbn(x,-n);
25*1e651e1eSRoland Levillain  *		log10(x) := n*log10_2hi + (n*log10_2lo + ivln10*ieee_log(x))
26*1e651e1eSRoland Levillain  *
27*1e651e1eSRoland Levillain  * Note 1:
28*1e651e1eSRoland Levillain  *	To guarantee ieee_log10(10**n)=n, where 10**n is normal, the rounding
29*1e651e1eSRoland Levillain  *	mode must set to Round-to-Nearest.
30*1e651e1eSRoland Levillain  * Note 2:
31*1e651e1eSRoland Levillain  *	[1/ieee_log(10)] rounded to 53 bits has error  .198   ulps;
32*1e651e1eSRoland Levillain  *	log10 is monotonic at all binary break points.
33*1e651e1eSRoland Levillain  *
34*1e651e1eSRoland Levillain  * Special cases:
35*1e651e1eSRoland Levillain  *	log10(x) is NaN with signal if x < 0;
36*1e651e1eSRoland Levillain  *	log10(+INF) is +INF with no signal; ieee_log10(0) is -INF with signal;
37*1e651e1eSRoland Levillain  *	log10(NaN) is that NaN with no signal;
38*1e651e1eSRoland Levillain  *	log10(10**N) = N  for N=0,1,...,22.
39*1e651e1eSRoland Levillain  *
40*1e651e1eSRoland Levillain  * Constants:
41*1e651e1eSRoland Levillain  * The hexadecimal values are the intended ones for the following constants.
42*1e651e1eSRoland Levillain  * The decimal values may be used, provided that the compiler will convert
43*1e651e1eSRoland Levillain  * from decimal to binary accurately enough to produce the hexadecimal values
44*1e651e1eSRoland Levillain  * shown.
45*1e651e1eSRoland Levillain  */
46*1e651e1eSRoland Levillain 
47*1e651e1eSRoland Levillain #include "fdlibm.h"
48*1e651e1eSRoland Levillain 
49*1e651e1eSRoland Levillain #ifdef __STDC__
50*1e651e1eSRoland Levillain static const double
51*1e651e1eSRoland Levillain #else
52*1e651e1eSRoland Levillain static double
53*1e651e1eSRoland Levillain #endif
54*1e651e1eSRoland Levillain two54      =  1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
55*1e651e1eSRoland Levillain ivln10     =  4.34294481903251816668e-01, /* 0x3FDBCB7B, 0x1526E50E */
56*1e651e1eSRoland Levillain log10_2hi  =  3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */
57*1e651e1eSRoland Levillain log10_2lo  =  3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */
58*1e651e1eSRoland Levillain 
59*1e651e1eSRoland Levillain static double zero   =  0.0;
60*1e651e1eSRoland Levillain 
61*1e651e1eSRoland Levillain #ifdef __STDC__
__ieee754_log10(double x)62*1e651e1eSRoland Levillain 	double __ieee754_log10(double x)
63*1e651e1eSRoland Levillain #else
64*1e651e1eSRoland Levillain 	double __ieee754_log10(x)
65*1e651e1eSRoland Levillain 	double x;
66*1e651e1eSRoland Levillain #endif
67*1e651e1eSRoland Levillain {
68*1e651e1eSRoland Levillain 	double y,z;
69*1e651e1eSRoland Levillain 	int i,k,hx;
70*1e651e1eSRoland Levillain 	unsigned lx;
71*1e651e1eSRoland Levillain 
72*1e651e1eSRoland Levillain 	hx = __HI(x);	/* high word of x */
73*1e651e1eSRoland Levillain 	lx = __LO(x);	/* low word of x */
74*1e651e1eSRoland Levillain 
75*1e651e1eSRoland Levillain         k=0;
76*1e651e1eSRoland Levillain         if (hx < 0x00100000) {                  /* x < 2**-1022  */
77*1e651e1eSRoland Levillain             if (((hx&0x7fffffff)|lx)==0)
78*1e651e1eSRoland Levillain                 return -two54/zero;             /* ieee_log(+-0)=-inf */
79*1e651e1eSRoland Levillain             if (hx<0) return (x-x)/zero;        /* ieee_log(-#) = NaN */
80*1e651e1eSRoland Levillain             k -= 54; x *= two54; /* subnormal number, scale up x */
81*1e651e1eSRoland Levillain             hx = __HI(x);                /* high word of x */
82*1e651e1eSRoland Levillain         }
83*1e651e1eSRoland Levillain 	if (hx >= 0x7ff00000) return x+x;
84*1e651e1eSRoland Levillain 	k += (hx>>20)-1023;
85*1e651e1eSRoland Levillain 	i  = ((unsigned)k&0x80000000)>>31;
86*1e651e1eSRoland Levillain         hx = (hx&0x000fffff)|((0x3ff-i)<<20);
87*1e651e1eSRoland Levillain         y  = (double)(k+i);
88*1e651e1eSRoland Levillain         __HI(x) = hx;
89*1e651e1eSRoland Levillain 	z  = y*log10_2lo + ivln10*__ieee754_log(x);
90*1e651e1eSRoland Levillain 	return  z+y*log10_2hi;
91*1e651e1eSRoland Levillain }
92