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
|