logbq.c 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. /* s_logbl.c -- long double version of s_logb.c.
  2. * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
  3. */
  4. /*
  5. * ====================================================
  6. * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  7. *
  8. * Developed at SunPro, a Sun Microsystems, Inc. business.
  9. * Permission to use, copy, modify, and distribute this
  10. * software is freely granted, provided that this notice
  11. * is preserved.
  12. * ====================================================
  13. */
  14. #if defined(LIBM_SCCS) && !defined(lint)
  15. static char rcsid[] = "$NetBSD: $";
  16. #endif
  17. /*
  18. * long double logbq(x)
  19. * IEEE 754 logb. Included to pass IEEE test suite. Not recommend.
  20. * Use ilogb instead.
  21. */
  22. #include "quadmath-imp.h"
  23. __float128
  24. logbq (__float128 x)
  25. {
  26. int64_t lx, hx, ex;
  27. GET_FLT128_WORDS64 (hx, lx, x);
  28. hx &= 0x7fffffffffffffffLL; /* high |x| */
  29. if ((hx | lx) == 0)
  30. return -1.0 / fabsq (x);
  31. if (hx >= 0x7fff000000000000LL)
  32. return x * x;
  33. if ((ex = hx >> 48) == 0) /* IEEE 754 logb */
  34. {
  35. /* POSIX specifies that denormal number is treated as
  36. though it were normalized. */
  37. int ma;
  38. if (hx == 0)
  39. ma = __builtin_clzll (lx) + 64;
  40. else
  41. ma = __builtin_clzll (hx);
  42. ex -= ma - 16;
  43. }
  44. return (__float128) (ex - 16383);
  45. }