Branch data Line data Source code
1 : : /* @(#)s_nextafter.c 5.1 93/09/24 */
2 : : /*
3 : : * ====================================================
4 : : * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 : : *
6 : : * Developed at SunPro, a Sun Microsystems, Inc. business.
7 : : * Permission to use, copy, modify, and distribute this
8 : : * software is freely granted, provided that this notice
9 : : * is preserved.
10 : : * ====================================================
11 : : */
12 : :
13 : : #include "cdefs-compat.h"
14 : : //__FBSDID("$FreeBSD: src/lib/msun/src/s_nextafter.c,v 1.12 2008/02/22 02:30:35 das Exp $");
15 : :
16 : : /* IEEE functions
17 : : * nextafter(x,y)
18 : : * return the next machine floating-point number of x in the
19 : : * direction toward y.
20 : : * Special cases:
21 : : */
22 : :
23 : : #include <float.h>
24 : : #include <openlibm_math.h>
25 : :
26 : : #include "math_private.h"
27 : :
28 : : OLM_DLLEXPORT double
29 : 11 : nextafter(double x, double y)
30 : : {
31 : : volatile double t;
32 : : int32_t hx,hy,ix,iy;
33 : : u_int32_t lx,ly;
34 : :
35 : 11 : EXTRACT_WORDS(hx,lx,x);
36 : 11 : EXTRACT_WORDS(hy,ly,y);
37 : 11 : ix = hx&0x7fffffff; /* |x| */
38 : 11 : iy = hy&0x7fffffff; /* |y| */
39 : :
40 [ + + + + : 11 : if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */
+ + ]
41 [ + + ]: 3 : ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0)) /* y is nan */
42 : 3 : return x+y;
43 [ + - ]: 8 : if(x==y) return y; /* x=y, return y */
44 [ # # ]: 0 : if((ix|lx)==0) { /* x == 0 */
45 : 0 : INSERT_WORDS(x,hy&0x80000000,1); /* return +-minsubnormal */
46 : 0 : t = x*x;
47 [ # # ]: 0 : if(t==x) return t; else return x; /* raise underflow flag */
48 : : }
49 [ # # ]: 0 : if(hx>=0) { /* x > 0 */
50 [ # # # # : 0 : if(hx>hy||((hx==hy)&&(lx>ly))) { /* x > y, x -= ulp */
# # ]
51 [ # # ]: 0 : if(lx==0) hx -= 1;
52 : 0 : lx -= 1;
53 : : } else { /* x < y, x += ulp */
54 : 0 : lx += 1;
55 [ # # ]: 0 : if(lx==0) hx += 1;
56 : : }
57 : : } else { /* x < 0 */
58 [ # # # # : 0 : if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */
# # # # ]
59 [ # # ]: 0 : if(lx==0) hx -= 1;
60 : 0 : lx -= 1;
61 : : } else { /* x > y, x += ulp */
62 : 0 : lx += 1;
63 [ # # ]: 0 : if(lx==0) hx += 1;
64 : : }
65 : : }
66 : 0 : hy = hx&0x7ff00000;
67 [ # # ]: 0 : if(hy>=0x7ff00000) return x+x; /* overflow */
68 [ # # ]: 0 : if(hy<0x00100000) { /* underflow */
69 : 0 : t = x*x;
70 [ # # ]: 0 : if(t!=x) { /* raise underflow flag */
71 : 0 : INSERT_WORDS(y,hx,lx);
72 : 0 : return y;
73 : : }
74 : : }
75 : 0 : INSERT_WORDS(x,hx,lx);
76 : 0 : return x;
77 : : }
78 : :
79 : : #if (LDBL_MANT_DIG == 53)
80 : : openlibm_weak_reference(nextafter, nexttoward);
81 : : openlibm_weak_reference(nextafter, nexttowardl);
82 : : openlibm_weak_reference(nextafter, nextafterl);
83 : : #endif
|