Branch data Line data Source code
1 : : /*
2 : : * ====================================================
3 : : * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
4 : : *
5 : : * Developed at SunPro, a Sun Microsystems, Inc. business.
6 : : * Permission to use, copy, modify, and distribute this
7 : : * software is freely granted, provided that this notice
8 : : * is preserved.
9 : : * ====================================================
10 : : */
11 : :
12 : : #include "cdefs-compat.h"
13 : : //__FBSDID("$FreeBSD: src/lib/msun/src/s_nexttowardf.c,v 1.3 2011/02/10 07:38:38 das Exp $");
14 : :
15 : : #include <float.h>
16 : : #include <openlibm_math.h>
17 : :
18 : : #include "fpmath.h"
19 : : #include "math_private.h"
20 : :
21 : : #define LDBL_INFNAN_EXP (LDBL_MAX_EXP * 2 - 1)
22 : :
23 : : #ifdef OLM_LONG_DOUBLE
24 : : OLM_DLLEXPORT float
25 : 0 : nexttowardf(float x, long double y)
26 : : {
27 : : union IEEEl2bits uy;
28 : : volatile float t;
29 : : int32_t hx,ix;
30 : :
31 : 0 : GET_FLOAT_WORD(hx,x);
32 : 0 : ix = hx&0x7fffffff; /* |x| */
33 : 0 : uy.e = y;
34 : :
35 [ # # ]: 0 : if((ix>0x7f800000) ||
36 [ # # ]: 0 : (uy.bits.exp == LDBL_INFNAN_EXP &&
37 [ # # ]: 0 : ((uy.bits.manh&~LDBL_NBIT)|uy.bits.manl) != 0))
38 : 0 : return x+y; /* x or y is nan */
39 [ # # ]: 0 : if(x==y) return (float)y; /* x=y, return y */
40 [ # # ]: 0 : if(ix==0) { /* x == 0 */
41 : 0 : SET_FLOAT_WORD(x,(uy.bits.sign<<31)|1);/* return +-minsubnormal */
42 : 0 : t = x*x;
43 [ # # ]: 0 : if(t==x) return t; else return x; /* raise underflow flag */
44 : : }
45 [ # # ]: 0 : if((hx>=0) ^ (x < y)) /* x -= ulp */
46 : 0 : hx -= 1;
47 : : else /* x += ulp */
48 : 0 : hx += 1;
49 : 0 : ix = hx&0x7f800000;
50 [ # # ]: 0 : if(ix>=0x7f800000) return x+x; /* overflow */
51 [ # # ]: 0 : if(ix<0x00800000) { /* underflow */
52 : 0 : t = x*x;
53 [ # # ]: 0 : if(t!=x) { /* raise underflow flag */
54 : 0 : SET_FLOAT_WORD(x,hx);
55 : 0 : return x;
56 : : }
57 : : }
58 : 0 : SET_FLOAT_WORD(x,hx);
59 : 0 : return x;
60 : : }
61 : : #endif
|