1
0

nextafterl.c 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /* origin: FreeBSD /usr/src/lib/msun/src/s_nextafterl.c */
  2. /*
  3. * ====================================================
  4. * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  5. *
  6. * Developed at SunPro, a Sun Microsystems, Inc. business.
  7. * Permission to use, copy, modify, and distribute this
  8. * software is freely granted, provided that this notice
  9. * is preserved.
  10. * ====================================================
  11. */
  12. /* IEEE functions
  13. * nextafter(x,y)
  14. * return the next machine floating-point number of x in the
  15. * direction toward y.
  16. * Special cases:
  17. */
  18. #include "libm.h"
  19. #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
  20. long double nextafterl(long double x, long double y)
  21. {
  22. return nextafter(x, y);
  23. }
  24. #elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
  25. long double nextafterl(long double x, long double y)
  26. {
  27. volatile long double t;
  28. union IEEEl2bits ux, uy;
  29. ux.e = x;
  30. uy.e = y;
  31. if ((ux.bits.exp == 0x7fff && ((ux.bits.manh&~LDBL_NBIT)|ux.bits.manl) != 0) ||
  32. (uy.bits.exp == 0x7fff && ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl) != 0))
  33. return x+y; /* x or y is nan */
  34. if (x == y)
  35. return y; /* x=y, return y */
  36. if (x == 0.0) {
  37. /* return +-minsubnormal */
  38. ux.bits.manh = 0;
  39. ux.bits.manl = 1;
  40. ux.bits.sign = uy.bits.sign;
  41. /* raise underflow flag */
  42. t = ux.e*ux.e;
  43. if (t == ux.e)
  44. return t;
  45. return ux.e;
  46. }
  47. if(x > 0.0 ^ x < y) { /* x -= ulp */
  48. if (ux.bits.manl == 0) {
  49. if ((ux.bits.manh&~LDBL_NBIT) == 0)
  50. ux.bits.exp--;
  51. ux.bits.manh = (ux.bits.manh - 1) | (ux.bits.manh & LDBL_NBIT);
  52. }
  53. ux.bits.manl--;
  54. } else { /* x += ulp */
  55. ux.bits.manl++;
  56. if (ux.bits.manl == 0) {
  57. ux.bits.manh = (ux.bits.manh + 1) | (ux.bits.manh & LDBL_NBIT);
  58. if ((ux.bits.manh&~LDBL_NBIT)==0)
  59. ux.bits.exp++;
  60. }
  61. }
  62. if (ux.bits.exp == 0x7fff) /* overflow */
  63. return x+x;
  64. if (ux.bits.exp == 0) { /* underflow */
  65. mask_nbit_l(ux);
  66. /* raise underflow flag */
  67. t = ux.e * ux.e;
  68. if (t != ux.e)
  69. return ux.e;
  70. }
  71. return ux.e;
  72. }
  73. #endif