1 /* $NetBSD: s_nextafterl.c,v 1.2 2010/09/17 20:39:39 christos Exp $ */
3 /* @(#)s_nextafter.c 5.1 93/09/24 */
5 * ====================================================
6 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 * Developed at SunPro, a Sun Microsystems, Inc. business.
9 * Permission to use, copy, modify, and distribute this
10 * software is freely granted, provided that this notice
12 * ====================================================
15 #include <sys/cdefs.h>
16 __RCSID("$NetBSD: s_nextafterl.c,v 1.2 2010/09/17 20:39:39 christos Exp $");
20 #include <machine/ieee.h>
23 #if LDBL_MAX_EXP != 0x4000
24 #error "Unsupported long double format"
30 * return the next machine floating-point number of x in the
33 * If x == y, y shall be returned
34 * If x or y is NaN, a NaN shall be returned
37 nextafterl(long double x
, long double y
)
39 volatile long double t
;
40 union ieee_ext_u ux
, uy
;
45 if ((ux
.extu_exp
== EXT_EXP_NAN
&&
46 ((ux
.extu_frach
&~ LDBL_NBIT
)|ux
.extu_fracl
) != 0) ||
47 (uy
.extu_exp
== EXT_EXP_NAN
&&
48 ((uy
.extu_frach
&~ LDBL_NBIT
)|uy
.extu_fracl
) != 0))
49 return x
+y
; /* x or y is nan */
51 if (x
== y
) return y
; /* x=y, return y */
54 ux
.extu_frach
= 0; /* return +-minsubnormal */
56 ux
.extu_sign
= uy
.extu_sign
;
57 t
= ux
.extu_ld
* ux
.extu_ld
;
61 return ux
.extu_ld
; /* raise underflow flag */
64 if ((x
>0.0) ^ (x
<y
)) { /* x -= ulp */
65 if (ux
.extu_fracl
== 0) {
66 if ((ux
.extu_frach
& ~LDBL_NBIT
) == 0)
68 ux
.extu_frach
= (ux
.extu_frach
- 1) |
69 (ux
.extu_frach
& LDBL_NBIT
);
72 } else { /* x += ulp */
74 if (ux
.extu_fracl
== 0) {
75 ux
.extu_frach
= (ux
.extu_frach
+ 1) |
76 (ux
.extu_frach
& LDBL_NBIT
);
77 if ((ux
.extu_frach
& ~LDBL_NBIT
) == 0)
82 if (ux
.extu_exp
== EXT_EXP_INF
)
83 return x
+x
; /* overflow */
85 if (ux
.extu_exp
== 0) { /* underflow */
87 t
= ux
.extu_ld
* ux
.extu_ld
;
88 if (t
!= ux
.extu_ld
) /* raise underflow flag */