xref: /openbsd/lib/libm/src/ld128/s_ilogbl.c (revision d722d60f)
1*d722d60fSkettenis /* s_ilogbl.c -- long double version of s_ilogb.c.
2*d722d60fSkettenis  * Conversion to 128-bit long double by Mark Kettenis, kettenis@openbsd.org.
3*d722d60fSkettenis  */
4*d722d60fSkettenis 
5*d722d60fSkettenis /*
6*d722d60fSkettenis  * ====================================================
7*d722d60fSkettenis  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8*d722d60fSkettenis  *
9*d722d60fSkettenis  * Developed at SunPro, a Sun Microsystems, Inc. business.
10*d722d60fSkettenis  * Permission to use, copy, modify, and distribute this
11*d722d60fSkettenis  * software is freely granted, provided that this notice
12*d722d60fSkettenis  * is preserved.
13*d722d60fSkettenis  * ====================================================
14*d722d60fSkettenis  */
15*d722d60fSkettenis 
16*d722d60fSkettenis /* ilogbl(long double x)
17*d722d60fSkettenis  * return the binary exponent of non-zero x
18*d722d60fSkettenis  * ilogb(0) = FP_ILOGB0
19*d722d60fSkettenis  * ilogb(NaN) = FP_ILOGBNAN (no signal is raised)
20*d722d60fSkettenis  * ilogb(inf) = INT_MAX (no signal is raised)
21*d722d60fSkettenis  */
22*d722d60fSkettenis 
23*d722d60fSkettenis #include <float.h>
24*d722d60fSkettenis #include <math.h>
25*d722d60fSkettenis 
26*d722d60fSkettenis #include "math_private.h"
27*d722d60fSkettenis 
28*d722d60fSkettenis int
ilogbl(long double x)29*d722d60fSkettenis ilogbl(long double x)
30*d722d60fSkettenis {
31*d722d60fSkettenis 	int64_t hx,lx;
32*d722d60fSkettenis 	int32_t ix;
33*d722d60fSkettenis 
34*d722d60fSkettenis 	GET_LDOUBLE_WORDS64(hx,lx,x);
35*d722d60fSkettenis 	hx &= 0x7fffffffffffffffLL;
36*d722d60fSkettenis 	if(hx<0x0001000000000000LL) {
37*d722d60fSkettenis 	    if((hx|lx)==0)
38*d722d60fSkettenis 		return FP_ILOGB0;	/* ilogb(0) = FP_ILOGB0 */
39*d722d60fSkettenis 	    else			/* subnormal x */
40*d722d60fSkettenis 		if(hx==0) {
41*d722d60fSkettenis 		    for (ix = -16431; lx>0; lx<<=1) ix -=1;
42*d722d60fSkettenis 		} else {
43*d722d60fSkettenis 		    for (ix = -16382, hx<<=15; hx>0; hx<<=1) ix -=1;
44*d722d60fSkettenis 		}
45*d722d60fSkettenis 	    return ix;
46*d722d60fSkettenis 	}
47*d722d60fSkettenis 	else if (hx<0x7fff000000000000LL) return (hx>>48)-16383;
48*d722d60fSkettenis 	else if (hx>0x7fff000000000000LL || lx!=0) return FP_ILOGBNAN;
49*d722d60fSkettenis 	else return INT_MAX;
50*d722d60fSkettenis }
51*d722d60fSkettenis DEF_STD(ilogbl);
52