4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
26 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
30 #pragma weak nexttoward = __nexttoward
33 * nexttoward(x, y) delivers the next representable number after x
34 * in the direction of y. If x and y are both zero, the result is
35 * zero with the same sign as y. If either x or y is NaN, the result
38 * If x != y and the result is infinite, overflow is raised; if
39 * x != y and the result is subnormal or zero, underflow is raised.
40 * (This is wrong, but it's what C99 apparently wants.)
53 0x7fffffff, 0xffffffff
68 #define _Q_cmp _Qp_cmp
71 extern enum fcc_type
_Q_cmp(const long double *, const long double *);
74 __nexttoward(double x
, long double y
) {
85 volatile double dummy
;
89 * It would be somewhat more efficient to check for NaN and
90 * zero operands before converting x to long double and then
91 * to code the comparison in line rather than calling _Q_cmp.
92 * However, since this code probably won't get used much,
93 * I'm opting in favor of simplicity instead.
96 hx
= (xx
.i
[0] & ~0x80000000) | xx
.i
[1];
98 /* check for each of four possible orderings */
99 rel
= _Q_cmp(&lx
, &y
);
100 if (rel
== fcc_unordered
)
103 if (rel
== fcc_equal
) {
104 if (hx
== 0) { /* x is zero; return zero with y's sign */
112 if (rel
== fcc_less
) {
113 if (hx
== 0) { /* x is zero */
115 xx
.i
[1] = 0x00000001;
116 } else if ((int)xx
.i
[0] >= 0) { /* x is positive */
124 if (hx
== 0) { /* x is zero */
125 xx
.i
[0] = 0x80000000;
126 xx
.i
[1] = 0x00000001;
127 } else if ((int)xx
.i
[0] >= 0) { /* x is positive */
136 /* raise exceptions as needed */
137 hx
= xx
.i
[0] & ~0x80000000;
138 if (hx
== 0x7ff00000) {
141 } else if (hx
< 0x00100000) {
163 __nexttoward(double x
, long double y
) {
170 volatile double dummy
;
173 hx
= (xx
.i
[1] & ~0x80000000) | xx
.i
[0];
175 /* check for each of four possible orderings */
176 if (isunordered(lx
, y
))
177 return ((double) (lx
+ y
));
183 if (hx
== 0) { /* x is zero */
184 xx
.i
[0] = 0x00000001;
186 } else if ((int)xx
.i
[1] >= 0) { /* x is positive */
194 if (hx
== 0) { /* x is zero */
195 xx
.i
[0] = 0x00000001;
196 xx
.i
[1] = 0x80000000;
197 } else if ((int)xx
.i
[1] >= 0) { /* x is positive */
206 /* raise exceptions as needed */
207 hx
= xx
.i
[1] & ~0x80000000;
208 if (hx
== 0x7ff00000) {
211 } else if (hx
< 0x00100000) {
220 #error Unknown architecture