xref: /minix3/lib/libm/src/s_nextafter.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
12fe8fb19SBen Gras /* @(#)s_nextafter.c 5.1 93/09/24 */
22fe8fb19SBen Gras /*
32fe8fb19SBen Gras  * ====================================================
42fe8fb19SBen Gras  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
52fe8fb19SBen Gras  *
62fe8fb19SBen Gras  * Developed at SunPro, a Sun Microsystems, Inc. business.
72fe8fb19SBen Gras  * Permission to use, copy, modify, and distribute this
82fe8fb19SBen Gras  * software is freely granted, provided that this notice
92fe8fb19SBen Gras  * is preserved.
102fe8fb19SBen Gras  * ====================================================
112fe8fb19SBen Gras  */
122fe8fb19SBen Gras 
132fe8fb19SBen Gras #include <sys/cdefs.h>
142fe8fb19SBen Gras #if defined(LIBM_SCCS) && !defined(lint)
15*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: s_nextafter.c,v 1.14 2014/03/18 18:20:37 riastradh Exp $");
162fe8fb19SBen Gras #endif
172fe8fb19SBen Gras 
182fe8fb19SBen Gras /* IEEE functions
192fe8fb19SBen Gras  *	nextafter(x,y)
202fe8fb19SBen Gras  *	return the next machine floating-point number of x in the
212fe8fb19SBen Gras  *	direction toward y.
222fe8fb19SBen Gras  *   Special cases:
232fe8fb19SBen Gras  */
242fe8fb19SBen Gras 
252fe8fb19SBen Gras #include "math.h"
262fe8fb19SBen Gras #include "math_private.h"
272fe8fb19SBen Gras 
2884d9c625SLionel Sambuc #ifndef __HAVE_LONG_DOUBLE
__strong_alias(nextafterl,nextafter)2984d9c625SLionel Sambuc __strong_alias(nextafterl, nextafter)
3084d9c625SLionel Sambuc #endif
3184d9c625SLionel Sambuc 
322fe8fb19SBen Gras double
332fe8fb19SBen Gras nextafter(double x, double y)
342fe8fb19SBen Gras {
352fe8fb19SBen Gras 	int32_t hx,hy,ix,iy;
362fe8fb19SBen Gras 	u_int32_t lx,ly;
372fe8fb19SBen Gras 
382fe8fb19SBen Gras 	EXTRACT_WORDS(hx,lx,x);
392fe8fb19SBen Gras 	EXTRACT_WORDS(hy,ly,y);
402fe8fb19SBen Gras 	ix = hx&0x7fffffff;		/* |x| */
412fe8fb19SBen Gras 	iy = hy&0x7fffffff;		/* |y| */
422fe8fb19SBen Gras 
432fe8fb19SBen Gras 	if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) ||   /* x is nan */
442fe8fb19SBen Gras 	   ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0))     /* y is nan */
452fe8fb19SBen Gras 	   return x+y;
4684d9c625SLionel Sambuc 	if(x==y) return y;		/* x=y, return y */
472fe8fb19SBen Gras 	if((ix|lx)==0) {			/* x == 0 */
482fe8fb19SBen Gras 	    INSERT_WORDS(x,hy&0x80000000,1);	/* return +-minsubnormal */
492fe8fb19SBen Gras 	    y = x*x;
502fe8fb19SBen Gras 	    if(y==x) return y; else return x;	/* raise underflow flag */
512fe8fb19SBen Gras 	}
522fe8fb19SBen Gras 	if(hx>=0) {				/* x > 0 */
532fe8fb19SBen Gras 	    if(hx>hy||((hx==hy)&&(lx>ly))) {	/* x > y, x -= ulp */
542fe8fb19SBen Gras 		if(lx==0) hx -= 1;
552fe8fb19SBen Gras 		lx -= 1;
562fe8fb19SBen Gras 	    } else {				/* x < y, x += ulp */
572fe8fb19SBen Gras 		lx += 1;
582fe8fb19SBen Gras 		if(lx==0) hx += 1;
592fe8fb19SBen Gras 	    }
602fe8fb19SBen Gras 	} else {				/* x < 0 */
612fe8fb19SBen Gras 	    if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */
622fe8fb19SBen Gras 		if(lx==0) hx -= 1;
632fe8fb19SBen Gras 		lx -= 1;
642fe8fb19SBen Gras 	    } else {				/* x > y, x += ulp */
652fe8fb19SBen Gras 		lx += 1;
662fe8fb19SBen Gras 		if(lx==0) hx += 1;
672fe8fb19SBen Gras 	    }
682fe8fb19SBen Gras 	}
692fe8fb19SBen Gras 	hy = hx&0x7ff00000;
702fe8fb19SBen Gras 	if(hy>=0x7ff00000) return x+x;	/* overflow  */
712fe8fb19SBen Gras 	if(hy<0x00100000) {		/* underflow */
722fe8fb19SBen Gras 	    y = x*x;
732fe8fb19SBen Gras 	    if(y!=x) {		/* raise underflow flag */
742fe8fb19SBen Gras 	        INSERT_WORDS(y,hx,lx);
752fe8fb19SBen Gras 		return y;
762fe8fb19SBen Gras 	    }
772fe8fb19SBen Gras 	}
782fe8fb19SBen Gras 	INSERT_WORDS(x,hx,lx);
792fe8fb19SBen Gras 	return x;
802fe8fb19SBen Gras }
81