sync
[bitrig.git] / lib / libm / src / s_ilogbl.c
blobda06cc9e6d81239f505fdb4583d05171a7e61bc8
1 /* $OpenBSD: s_ilogbl.c,v 1.1 2008/12/09 20:00:35 martynas Exp $ */
2 /*
3 * From: @(#)s_ilogb.c 5.1 93/09/24
4 * ====================================================
5 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
7 * Developed at SunPro, a Sun Microsystems, Inc. business.
8 * Permission to use, copy, modify, and distribute this
9 * software is freely granted, provided that this notice
10 * is preserved.
11 * ====================================================
14 #include <sys/types.h>
15 #include <machine/ieee.h>
16 #include <float.h>
17 #include <limits.h>
18 #include <math.h>
20 int
21 ilogbl(long double x)
23 struct ieee_ext *p = (struct ieee_ext *)&x;
24 unsigned long m;
25 int b;
27 if (p->ext_exp == 0) {
28 if ((p->ext_fracl
29 #ifdef EXT_FRACLMBITS
30 | p->ext_fraclm
31 #endif /* EXT_FRACLMBITS */
32 #ifdef EXT_FRACHMBITS
33 | p->ext_frachm
34 #endif /* EXT_FRACHMBITS */
35 | p->ext_frach) == 0)
36 return (FP_ILOGB0);
37 /* denormalized */
38 if (p->ext_frach == 0
39 #ifdef EXT_FRACHMBITS
40 && p->ext_frachm == 0
41 #endif
42 ) {
43 m = 1lu << (EXT_FRACLBITS - 1);
44 for (b = EXT_FRACHBITS; !(p->ext_fracl & m); m >>= 1)
45 b++;
46 #if defined(EXT_FRACHMBITS) && defined(EXT_FRACLMBITS)
47 m = 1lu << (EXT_FRACLMBITS - 1);
48 for (b += EXT_FRACHMBITS; !(p->ext_fraclm & m); m >>= 1)
49 b++;
50 #endif /* defined(EXT_FRACHMBITS) && defined(EXT_FRACLMBITS) */
51 } else {
52 m = 1lu << (EXT_FRACHBITS - 1);
53 for (b = 0; !(p->ext_frach & m); m >>= 1)
54 b++;
55 #ifdef EXT_FRACHMBITS
56 m = 1lu << (EXT_FRACHMBITS - 1);
57 for (; !(p->ext_frachm & m); m >>= 1)
58 b++;
59 #endif /* EXT_FRACHMBITS */
61 #ifdef EXT_IMPLICIT_NBIT
62 b++;
63 #endif
64 return (LDBL_MIN_EXP - b - 1);
65 } else if (p->ext_exp < (LDBL_MAX_EXP << 1) - 1)
66 return (p->ext_exp - LDBL_MAX_EXP + 1);
67 else if (p->ext_fracl != 0
68 #ifdef EXT_FRACLMBITS
69 || p->ext_fraclm != 0
70 #endif /* EXT_FRACLMBITS */
71 #ifdef EXT_FRACHMBITS
72 || p->ext_frachm != 0
73 #endif /* EXT_FRACHMBITS */
74 || p->ext_frach != 0)
75 return (FP_ILOGBNAN);
76 else
77 return (INT_MAX);