nextafterl.c raw

   1  #include "libm.h"
   2  
   3  #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
   4  long double nextafterl(long double x, long double y)
   5  {
   6  	return nextafter(x, y);
   7  }
   8  #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
   9  long double nextafterl(long double x, long double y)
  10  {
  11  	union ldshape ux, uy;
  12  
  13  	if (isnan(x) || isnan(y))
  14  		return x + y;
  15  	if (x == y)
  16  		return y;
  17  	ux.f = x;
  18  	if (x == 0) {
  19  		uy.f = y;
  20  		ux.i.m = 1;
  21  		ux.i.se = uy.i.se & 0x8000;
  22  	} else if ((x < y) == !(ux.i.se & 0x8000)) {
  23  		ux.i.m++;
  24  		if (ux.i.m << 1 == 0) {
  25  			ux.i.m = 1ULL << 63;
  26  			ux.i.se++;
  27  		}
  28  	} else {
  29  		if (ux.i.m << 1 == 0) {
  30  			ux.i.se--;
  31  			if (ux.i.se)
  32  				ux.i.m = 0;
  33  		}
  34  		ux.i.m--;
  35  	}
  36  	/* raise overflow if ux is infinite and x is finite */
  37  	if ((ux.i.se & 0x7fff) == 0x7fff)
  38  		return x + x;
  39  	/* raise underflow if ux is subnormal or zero */
  40  	if ((ux.i.se & 0x7fff) == 0)
  41  		FORCE_EVAL(x*x + ux.f*ux.f);
  42  	return ux.f;
  43  }
  44  #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
  45  long double nextafterl(long double x, long double y)
  46  {
  47  	union ldshape ux, uy;
  48  
  49  	if (isnan(x) || isnan(y))
  50  		return x + y;
  51  	if (x == y)
  52  		return y;
  53  	ux.f = x;
  54  	if (x == 0) {
  55  		uy.f = y;
  56  		ux.i.lo = 1;
  57  		ux.i.se = uy.i.se & 0x8000;
  58  	} else if ((x < y) == !(ux.i.se & 0x8000)) {
  59  		ux.i2.lo++;
  60  		if (ux.i2.lo == 0)
  61  			ux.i2.hi++;
  62  	} else {
  63  		if (ux.i2.lo == 0)
  64  			ux.i2.hi--;
  65  		ux.i2.lo--;
  66  	}
  67  	/* raise overflow if ux is infinite and x is finite */
  68  	if ((ux.i.se & 0x7fff) == 0x7fff)
  69  		return x + x;
  70  	/* raise underflow if ux is subnormal or zero */
  71  	if ((ux.i.se & 0x7fff) == 0)
  72  		FORCE_EVAL(x*x + ux.f*ux.f);
  73  	return ux.f;
  74  }
  75  #endif
  76