s_nextafter.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. /*
  2. * ====================================================
  3. * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  4. *
  5. * Developed at SunPro, a Sun Microsystems, Inc. business.
  6. * Permission to use, copy, modify, and distribute this
  7. * software is freely granted, provided that this notice
  8. * is preserved.
  9. * ====================================================
  10. */
  11. /* IEEE functions
  12. * nextafter(x,y)
  13. * return the next machine floating-point number of x in the
  14. * direction toward y.
  15. * Special cases:
  16. */
  17. #include "math.h"
  18. #include "math_private.h"
  19. double nextafter(double x, double y)
  20. {
  21. int32_t hx,hy,ix,iy;
  22. u_int32_t lx,ly;
  23. EXTRACT_WORDS(hx,lx,x);
  24. EXTRACT_WORDS(hy,ly,y);
  25. ix = hx&0x7fffffff; /* |x| */
  26. iy = hy&0x7fffffff; /* |y| */
  27. if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */
  28. ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0)) /* y is nan */
  29. return x+y;
  30. if(x==y) return y; /* x=y, return y */
  31. if((ix|lx)==0) { /* x == 0 */
  32. INSERT_WORDS(x,hy&0x80000000,1); /* return +-minsubnormal */
  33. y = x*x;
  34. if(y==x) return y; else return x; /* raise underflow flag */
  35. }
  36. if(hx>=0) { /* x > 0 */
  37. if(hx>hy||((hx==hy)&&(lx>ly))) { /* x > y, x -= ulp */
  38. if(lx==0) hx -= 1;
  39. lx -= 1;
  40. } else { /* x < y, x += ulp */
  41. lx += 1;
  42. if(lx==0) hx += 1;
  43. }
  44. } else { /* x < 0 */
  45. if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */
  46. if(lx==0) hx -= 1;
  47. lx -= 1;
  48. } else { /* x > y, x += ulp */
  49. lx += 1;
  50. if(lx==0) hx += 1;
  51. }
  52. }
  53. hy = hx&0x7ff00000;
  54. if(hy>=0x7ff00000) return x+x; /* overflow */
  55. if(hy<0x00100000) { /* underflow */
  56. y = x*x;
  57. if(y!=x) { /* raise underflow flag */
  58. INSERT_WORDS(y,hx,lx);
  59. return y;
  60. }
  61. }
  62. INSERT_WORDS(x,hx,lx);
  63. return x;
  64. }
  65. libm_hidden_def(nextafter)
  66. strong_alias_untyped(nextafter, nexttoward)
  67. libm_hidden_def(nexttoward)