18346e333Sjtc /* s_ilogbf.c -- float version of s_ilogb.c.
28346e333Sjtc * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
38346e333Sjtc */
48346e333Sjtc
58346e333Sjtc /*
68346e333Sjtc * ====================================================
78346e333Sjtc * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
88346e333Sjtc *
98346e333Sjtc * Developed at SunPro, a Sun Microsystems, Inc. business.
108346e333Sjtc * Permission to use, copy, modify, and distribute this
118346e333Sjtc * software is freely granted, provided that this notice
128346e333Sjtc * is preserved.
138346e333Sjtc * ====================================================
148346e333Sjtc */
158346e333Sjtc
1661187201Slukem #include <sys/cdefs.h>
17d1f06e0bSjtc #if defined(LIBM_SCCS) && !defined(lint)
18*b1803eb8Schristos __RCSID("$NetBSD: s_ilogbf.c,v 1.10 2016/08/26 08:20:31 christos Exp $");
198346e333Sjtc #endif
208346e333Sjtc
215b36f996Schristos #include <math.h>
22*b1803eb8Schristos #define __TEST_FENV
235b36f996Schristos #include <fenv.h>
24*b1803eb8Schristos #ifndef __HAVE_FENV
25*b1803eb8Schristos #define feraiseexcept(a)
26*b1803eb8Schristos #endif
278346e333Sjtc #include "math_private.h"
288346e333Sjtc
29aa30599eSwiz int
ilogbf(float x)30aa30599eSwiz ilogbf(float x)
318346e333Sjtc {
32b0c9d092Sjtc int32_t hx, ix;
338346e333Sjtc
348346e333Sjtc GET_FLOAT_WORD(hx, x);
358346e333Sjtc hx &= 0x7fffffff;
368346e333Sjtc if (hx < 0x00800000) {
375b36f996Schristos if (hx == 0) {
385b36f996Schristos feraiseexcept(FE_INVALID);
399074d593Smatt return FP_ILOGB0; /* ilogb(0) = 0x80000001 */
405b36f996Schristos }
418346e333Sjtc for (ix = -126, hx <<= 8; hx > 0; hx <<= 1) ix -= 1;
428346e333Sjtc return ix;
438346e333Sjtc }
445b36f996Schristos
455b36f996Schristos if (hx < 0x7f800000) {
465b36f996Schristos return (hx >> 23) - 127;
475b36f996Schristos }
485b36f996Schristos
495b36f996Schristos feraiseexcept(FE_INVALID);
505b36f996Schristos return isnan(x) ? FP_ILOGBNAN : INT_MAX;
518346e333Sjtc }
52