| /* s_nextafterf.c -- float version of s_nextafter.c. | 
 |  * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. | 
 |  */ | 
 |  | 
 | /* | 
 |  * ==================================================== | 
 |  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. | 
 |  * | 
 |  * Developed at SunPro, a Sun Microsystems, Inc. business. | 
 |  * Permission to use, copy, modify, and distribute this | 
 |  * software is freely granted, provided that this notice | 
 |  * is preserved. | 
 |  * ==================================================== | 
 |  */ | 
 |  | 
 | #include "math.h" | 
 | #include "math_private.h" | 
 |  | 
 | float nextafterf(float x, float y) | 
 | { | 
 | 	int32_t hx, hy, ix, iy; | 
 |  | 
 | 	GET_FLOAT_WORD(hx, x); | 
 | 	GET_FLOAT_WORD(hy, y); | 
 | 	ix = hx & 0x7fffffff;		/* |x| */ | 
 | 	iy = hy & 0x7fffffff;		/* |y| */ | 
 |  | 
 | 	/* x is nan or y is nan? */ | 
 | 	if ((ix > 0x7f800000) || (iy > 0x7f800000)) | 
 | 		return x + y; | 
 |  | 
 | 	if (x == y) | 
 | 		return y; | 
 |  | 
 | 	if (ix == 0) { /* x == 0? */ | 
 | /* glibc 2.4 does not seem to set underflow? */ | 
 | /*		float u; */ | 
 | 		/* return +-minsubnormal */ | 
 | 		SET_FLOAT_WORD(x, (hy & 0x80000000) | 1); | 
 | /*		u = x * x;     raise underflow flag */ | 
 | /*		math_force_eval(u); */ | 
 | 		return x; | 
 | 	} | 
 |  | 
 | 	if (hx >= 0) { /* x > 0 */ | 
 | 		if (hx > hy) { /* x > y: x -= ulp */ | 
 | 			hx -= 1; | 
 | 		} else { /* x < y: x += ulp */ | 
 | 			hx += 1; | 
 | 		} | 
 | 	} else { /* x < 0 */ | 
 | 		if (hy >= 0 || hx > hy) { /* x < y: x -= ulp */ | 
 | 			hx -= 1; | 
 | 		} else { /* x > y: x += ulp */ | 
 | 			hx += 1; | 
 | 		} | 
 | 	} | 
 | 	hy = hx & 0x7f800000; | 
 | 	if (hy >= 0x7f800000) { | 
 | 		x = x + x; /* overflow */ | 
 | 		return x; /* overflow */ | 
 | 	} | 
 | 	if (hy < 0x00800000) { | 
 | 		float u = x * x; /* underflow */ | 
 | 		math_force_eval(u); /* raise underflow flag */ | 
 | 	} | 
 | 	SET_FLOAT_WORD(x, hx); | 
 | 	return x; | 
 | } | 
 |  | 
 | #if 0 | 
 | /* "testprog N a b" | 
 |  * calculates a = nextafterf(a, b) and prints a as float | 
 |  * and as raw bytes; repeats it N times. | 
 |  */ | 
 | #include <stdio.h> | 
 | #include <stdlib.h> | 
 | #include <math.h> | 
 | int main(int argc, char **argv) | 
 | { | 
 |         int cnt, i; | 
 |         float a, b; | 
 |         cnt = atoi(argv[1]); | 
 |         a = strtod(argv[2], NULL); | 
 |         b = strtod(argv[3], NULL); | 
 |         while (cnt-- > 0) { | 
 |                 for (i = 0; i < sizeof(a); i++) { | 
 |                         unsigned char c = ((char*)(&a))[i]; | 
 |                         printf("%x%x", (c >> 4), (c & 0xf)); | 
 |                 } | 
 |                 printf(" %f\n", a); | 
 |                 a = nextafterf(a, b); | 
 |         } | 
 |         return 0; | 
 | } | 
 | #endif |