| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 | /* 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
 |