Branch data Line data Source code
1 : : /* s_nextafterf.c -- float version of s_nextafter.c.
2 : : * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
3 : : */
4 : :
5 : : /*
6 : : * ====================================================
7 : : * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 : : *
9 : : * Developed at SunPro, a Sun Microsystems, Inc. business.
10 : : * Permission to use, copy, modify, and distribute this
11 : : * software is freely granted, provided that this notice
12 : : * is preserved.
13 : : * ====================================================
14 : : */
15 : :
16 : : #include "cdefs-compat.h"
17 : : //__FBSDID("$FreeBSD: src/lib/msun/src/s_nextafterf.c,v 1.11 2008/02/22 02:30:35 das Exp $");
18 : :
19 : : #include <openlibm_math.h>
20 : :
21 : : #include "math_private.h"
22 : :
23 : : OLM_DLLEXPORT float
24 : 11 : nextafterf(float x, float y)
25 : : {
26 : : volatile float t;
27 : : int32_t hx,hy,ix,iy;
28 : :
29 : 11 : GET_FLOAT_WORD(hx,x);
30 : 11 : GET_FLOAT_WORD(hy,y);
31 : 11 : ix = hx&0x7fffffff; /* |x| */
32 : 11 : iy = hy&0x7fffffff; /* |y| */
33 : :
34 [ + + + + ]: 11 : if((ix>0x7f800000) || /* x is nan */
35 : : (iy>0x7f800000)) /* y is nan */
36 : 3 : return x+y;
37 [ + - ]: 8 : if(x==y) return y; /* x=y, return y */
38 [ # # ]: 0 : if(ix==0) { /* x == 0 */
39 : 0 : SET_FLOAT_WORD(x,(hy&0x80000000)|1);/* return +-minsubnormal */
40 : 0 : t = x*x;
41 [ # # ]: 0 : if(t==x) return t; else return x; /* raise underflow flag */
42 : : }
43 [ # # ]: 0 : if(hx>=0) { /* x > 0 */
44 [ # # ]: 0 : if(hx>hy) { /* x > y, x -= ulp */
45 : 0 : hx -= 1;
46 : : } else { /* x < y, x += ulp */
47 : 0 : hx += 1;
48 : : }
49 : : } else { /* x < 0 */
50 [ # # # # ]: 0 : if(hy>=0||hx>hy){ /* x < y, x -= ulp */
51 : 0 : hx -= 1;
52 : : } else { /* x > y, x += ulp */
53 : 0 : hx += 1;
54 : : }
55 : : }
56 : 0 : hy = hx&0x7f800000;
57 [ # # ]: 0 : if(hy>=0x7f800000) return x+x; /* overflow */
58 [ # # ]: 0 : if(hy<0x00800000) { /* underflow */
59 : 0 : t = x*x;
60 [ # # ]: 0 : if(t!=x) { /* raise underflow flag */
61 : 0 : SET_FLOAT_WORD(y,hx);
62 : 0 : return y;
63 : : }
64 : : }
65 : 0 : SET_FLOAT_WORD(x,hx);
66 : 0 : return x;
67 : : }
|