ilogbq.c 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /* ilogbq.c -- __float128 version of s_ilogb.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. /* ilogbl(__float128 x)
  18. * return the binary exponent of non-zero x
  19. * ilogbl(0) = FP_ILOGB0
  20. * ilogbl(NaN) = FP_ILOGBNAN (no signal is raised)
  21. * ilogbl(+-Inf) = INT_MAX (no signal is raised)
  22. */
  23. #include <limits.h>
  24. #include <math.h>
  25. #include <errno.h>
  26. #include "quadmath-imp.h"
  27. #ifndef FP_ILOGB0
  28. # define FP_ILOGB0 INT_MIN
  29. #endif
  30. #ifndef FP_ILOGBNAN
  31. # define FP_ILOGBNAN INT_MAX
  32. #endif
  33. int
  34. ilogbq (__float128 x)
  35. {
  36. int64_t hx,lx;
  37. int ix;
  38. GET_FLT128_WORDS64(hx,lx,x);
  39. hx &= 0x7fffffffffffffffLL;
  40. if(hx <= 0x0001000000000000LL) {
  41. if((hx|lx)==0)
  42. {
  43. errno = EDOM;
  44. #ifdef USE_FENV_H
  45. feraiseexcept (FE_INVALID);
  46. #endif
  47. return FP_ILOGB0; /* ilogbl(0) = FP_ILOGB0 */
  48. }
  49. else /* subnormal x */
  50. if(hx==0) {
  51. for (ix = -16431; lx>0; lx<<=1) ix -=1;
  52. } else {
  53. for (ix = -16382, hx<<=15; hx>0; hx<<=1) ix -=1;
  54. }
  55. return ix;
  56. }
  57. else if (hx<0x7fff000000000000LL) return (hx>>48)-0x3fff;
  58. else if (FP_ILOGBNAN != INT_MAX) {
  59. /* ISO C99 requires ilogbl(+-Inf) == INT_MAX. */
  60. if (((hx^0x7fff000000000000LL)|lx) == 0)
  61. {
  62. errno = EDOM;
  63. #ifdef USE_FENV_H
  64. feraiseexcept (FE_INVALID);
  65. #endif
  66. return INT_MAX;
  67. }
  68. }
  69. errno = EDOM;
  70. #ifdef USE_FENV_H
  71. feraiseexcept (FE_INVALID);
  72. #endif
  73. return FP_ILOGBNAN;
  74. }