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