s_nextafter.c revision 2116
12116Sjkh/* @(#)s_nextafter.c 5.1 93/09/24 */
22116Sjkh/*
32116Sjkh * ====================================================
42116Sjkh * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
52116Sjkh *
62116Sjkh * Developed at SunPro, a Sun Microsystems, Inc. business.
72116Sjkh * Permission to use, copy, modify, and distribute this
82116Sjkh * software is freely granted, provided that this notice
92116Sjkh * is preserved.
102116Sjkh * ====================================================
112116Sjkh */
122116Sjkh
132116Sjkh#ifndef lint
142116Sjkhstatic char rcsid[] = "$Id: s_nextafter.c,v 1.6 1994/08/18 23:07:13 jtc Exp $";
152116Sjkh#endif
162116Sjkh
172116Sjkh/* IEEE functions
182116Sjkh *	nextafter(x,y)
192116Sjkh *	return the next machine floating-point number of x in the
202116Sjkh *	direction toward y.
212116Sjkh *   Special cases:
222116Sjkh */
232116Sjkh
242116Sjkh#include "math.h"
252116Sjkh#include "math_private.h"
262116Sjkh
272116Sjkh#ifdef __STDC__
282116Sjkh	double nextafter(double x, double y)
292116Sjkh#else
302116Sjkh	double nextafter(x,y)
312116Sjkh	double x,y;
322116Sjkh#endif
332116Sjkh{
342116Sjkh	int32_t hx,hy,ix,iy;
352116Sjkh	u_int32_t lx,ly;
362116Sjkh
372116Sjkh	EXTRACT_WORDS(hx,lx,x);
382116Sjkh	EXTRACT_WORDS(hy,ly,y);
392116Sjkh	ix = hx&0x7fffffff;		/* |x| */
402116Sjkh	iy = hy&0x7fffffff;		/* |y| */
412116Sjkh
422116Sjkh	if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) ||   /* x is nan */
432116Sjkh	   ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0))     /* y is nan */
442116Sjkh	   return x+y;
452116Sjkh	if(x==y) return x;		/* x=y, return x */
462116Sjkh	if((ix|lx)==0) {			/* x == 0 */
472116Sjkh	    INSERT_WORDS(x,hy&0x80000000,1);	/* return +-minsubnormal */
482116Sjkh	    y = x*x;
492116Sjkh	    if(y==x) return y; else return x;	/* raise underflow flag */
502116Sjkh	}
512116Sjkh	if(hx>=0) {				/* x > 0 */
522116Sjkh	    if(hx>hy||((hx==hy)&&(lx>ly))) {	/* x > y, x -= ulp */
532116Sjkh		if(lx==0) hx -= 1;
542116Sjkh		lx -= 1;
552116Sjkh	    } else {				/* x < y, x += ulp */
562116Sjkh		lx += 1;
572116Sjkh		if(lx==0) hx += 1;
582116Sjkh	    }
592116Sjkh	} else {				/* x < 0 */
602116Sjkh	    if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */
612116Sjkh		if(lx==0) hx -= 1;
622116Sjkh		lx -= 1;
632116Sjkh	    } else {				/* x > y, x += ulp */
642116Sjkh		lx += 1;
652116Sjkh		if(lx==0) hx += 1;
662116Sjkh	    }
672116Sjkh	}
682116Sjkh	hy = hx&0x7ff00000;
692116Sjkh	if(hy>=0x7ff00000) return x+x;	/* overflow  */
702116Sjkh	if(hy<0x00100000) {		/* underflow */
712116Sjkh	    y = x*x;
722116Sjkh	    if(y!=x) {		/* raise underflow flag */
732116Sjkh	        INSERT_WORDS(y,hx,lx);
742116Sjkh		return y;
752116Sjkh	    }
762116Sjkh	}
772116Sjkh	INSERT_WORDS(x,hx,lx);
782116Sjkh	return x;
792116Sjkh}
80