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