xref: /freebsd/lib/msun/src/s_logbl.c (revision 0dd5a5603e7a33d976f8e6015620bbc79839c609)
16821aba9SDavid Schultz /*
26821aba9SDavid Schultz  * ====================================================
36821aba9SDavid Schultz  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
46821aba9SDavid Schultz  *
56821aba9SDavid Schultz  * Developed at SunPro, a Sun Microsystems, Inc. business.
66821aba9SDavid Schultz  * Permission to use, copy, modify, and distribute this
76821aba9SDavid Schultz  * software is freely granted, provided that this notice
86821aba9SDavid Schultz  * is preserved.
96821aba9SDavid Schultz  * ====================================================
106821aba9SDavid Schultz  */
116821aba9SDavid Schultz 
126821aba9SDavid Schultz #include <float.h>
136821aba9SDavid Schultz #include <limits.h>
146821aba9SDavid Schultz #include <math.h>
156821aba9SDavid Schultz 
166821aba9SDavid Schultz #include "fpmath.h"
176821aba9SDavid Schultz 
186821aba9SDavid Schultz long double
logbl(long double x)196821aba9SDavid Schultz logbl(long double x)
206821aba9SDavid Schultz {
216821aba9SDavid Schultz 	union IEEEl2bits u;
226821aba9SDavid Schultz 	unsigned long m;
236821aba9SDavid Schultz 	int b;
246821aba9SDavid Schultz 
256821aba9SDavid Schultz 	u.e = x;
266821aba9SDavid Schultz 	if (u.bits.exp == 0) {
276821aba9SDavid Schultz 		if ((u.bits.manl | u.bits.manh) == 0) {	/* x == 0 */
286821aba9SDavid Schultz 			u.bits.sign = 1;
296821aba9SDavid Schultz 			return (1.0L / u.e);
306821aba9SDavid Schultz 		}
316821aba9SDavid Schultz 		/* denormalized */
326821aba9SDavid Schultz 		if (u.bits.manh == 0) {
336821aba9SDavid Schultz 			m = 1lu << (LDBL_MANL_SIZE - 1);
346821aba9SDavid Schultz 			for (b = LDBL_MANH_SIZE; !(u.bits.manl & m); m >>= 1)
356821aba9SDavid Schultz 				b++;
366821aba9SDavid Schultz 		} else {
376821aba9SDavid Schultz 			m = 1lu << (LDBL_MANH_SIZE - 1);
386821aba9SDavid Schultz 			for (b = 0; !(u.bits.manh & m); m >>= 1)
396821aba9SDavid Schultz 				b++;
406821aba9SDavid Schultz 		}
416821aba9SDavid Schultz #ifdef LDBL_IMPLICIT_NBIT
426821aba9SDavid Schultz 		b++;
436821aba9SDavid Schultz #endif
446821aba9SDavid Schultz 		return ((long double)(LDBL_MIN_EXP - b - 1));
456821aba9SDavid Schultz 	}
466821aba9SDavid Schultz 	if (u.bits.exp < (LDBL_MAX_EXP << 1) - 1)	/* normal */
476821aba9SDavid Schultz 		return ((long double)(u.bits.exp - LDBL_MAX_EXP + 1));
486821aba9SDavid Schultz 	else						/* +/- inf or nan */
496821aba9SDavid Schultz 		return (x * x);
506821aba9SDavid Schultz }
51