1 /* s_nextafterl.c -- long double version of s_nextafter.c.
2 * Conversion to IEEE quad long double by Jakub Jelinek, jj@ultra.linux.cz.
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
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
13 * ====================================================
16 #if defined(LIBM_SCCS) && !defined(lint)
17 static char rcsid
[] = "$NetBSD: $";
22 * return the next machine floating-point number of x in the
28 #include <math_private.h>
29 #include <math_ldbl_opt.h>
32 long double __nextafterl(long double x
, long double y
)
34 long double __nextafterl(x
,y
)
38 int64_t hx
,hy
,ihx
,ihy
,ilx
;
41 GET_LDOUBLE_WORDS64(hx
,lx
,x
);
42 GET_LDOUBLE_WORDS64(hy
,ly
,y
);
43 ihx
= hx
&0x7fffffffffffffffLL
; /* |hx| */
44 ilx
= lx
&0x7fffffffffffffffLL
; /* |lx| */
45 ihy
= hy
&0x7fffffffffffffffLL
; /* |hy| */
47 if((((ihx
&0x7ff0000000000000LL
)==0x7ff0000000000000LL
)&&
48 ((ihx
&0x000fffffffffffffLL
)!=0)) || /* x is nan */
49 (((ihy
&0x7ff0000000000000LL
)==0x7ff0000000000000LL
)&&
50 ((ihy
&0x000fffffffffffffLL
)!=0))) /* y is nan */
51 return x
+y
; /* signal the nan */
53 return y
; /* x=y, return y */
54 if(ihx
== 0 && ilx
== 0) { /* x == 0 */
56 hy
= (hy
& 0x8000000000000000ULL
) | 1;
57 SET_LDOUBLE_WORDS64(x
,hy
,0ULL);/* return +-minsubnormal */
58 u
= math_opt_barrier (x
);
60 math_force_eval (u
); /* raise underflow flag */
65 if(x
> y
) { /* x > y, x -= ulp */
66 if((hx
==0xffefffffffffffffLL
)&&(lx
==0xfc8ffffffffffffeLL
))
67 return x
+x
; /* overflow, return -inf */
68 if (hx
>= 0x7ff0000000000000LL
) {
69 SET_LDOUBLE_WORDS64(u
,0x7fefffffffffffffLL
,0x7c8ffffffffffffeLL
);
72 if(ihx
<= 0x0360000000000000LL
) { /* x <= LDBL_MIN */
73 u
= math_opt_barrier (x
);
74 x
-= __LDBL_DENORM_MIN__
;
75 if (ihx
< 0x0360000000000000LL
76 || (hx
> 0 && (int64_t) lx
<= 0)
77 || (hx
< 0 && (int64_t) lx
> 1)) {
79 math_force_eval (u
); /* raise underflow flag */
83 if (ihx
< 0x06a0000000000000LL
) { /* ulp will denormal */
84 SET_LDOUBLE_WORDS64(u
,(hx
&0x7ff0000000000000LL
),0ULL);
85 u
*= 0x1.0000000000000p
-105L;
87 SET_LDOUBLE_WORDS64(u
,(hx
&0x7ff0000000000000LL
)-0x0690000000000000LL
,0ULL);
89 } else { /* x < y, x += ulp */
90 if((hx
==0x7fefffffffffffffLL
)&&(lx
==0x7c8ffffffffffffeLL
))
91 return x
+x
; /* overflow, return +inf */
92 if ((u_int64_t
) hx
>= 0xfff0000000000000ULL
) {
93 SET_LDOUBLE_WORDS64(u
,0xffefffffffffffffLL
,0xfc8ffffffffffffeLL
);
96 if(ihx
<= 0x0360000000000000LL
) { /* x <= LDBL_MIN */
97 u
= math_opt_barrier (x
);
98 x
+= __LDBL_DENORM_MIN__
;
99 if (ihx
< 0x0360000000000000LL
100 || (hx
> 0 && (int64_t) lx
< 0 && lx
!= 0x8000000000000001LL
)
101 || (hx
< 0 && (int64_t) lx
>= 0)) {
103 math_force_eval (u
); /* raise underflow flag */
105 if (x
== 0.0L) /* handle negative __LDBL_DENORM_MIN__ case */
109 if (ihx
< 0x06a0000000000000LL
) { /* ulp will denormal */
110 SET_LDOUBLE_WORDS64(u
,(hx
&0x7ff0000000000000LL
),0ULL);
111 u
*= 0x1.0000000000000p
-105L;
113 SET_LDOUBLE_WORDS64(u
,(hx
&0x7ff0000000000000LL
)-0x0690000000000000LL
,0ULL);
117 strong_alias (__nextafterl
, __nexttowardl
)
118 long_double_symbol (libm
, __nextafterl
, nextafterl
);
119 long_double_symbol (libm
, __nexttowardl
, nexttowardl
);