summaryrefslogtreecommitdiff
path: root/usr/src/libm/src/Q/nextafterl.c
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2012-09-11 19:12:10 +0400
committerIgor Pashev <pashev.igor@gmail.com>2012-09-11 19:12:10 +0400
commit19700b860d9ec70d01e885d92c3d4f62fd052873 (patch)
treeb6b265cd81fb97b4675f4a285f397479609fdf18 /usr/src/libm/src/Q/nextafterl.c
downloadlibm-19700b860d9ec70d01e885d92c3d4f62fd052873.tar.gz
Imported Upstream version 20060131HEADupstream/20060131upstreammaster
Diffstat (limited to 'usr/src/libm/src/Q/nextafterl.c')
-rw-r--r--usr/src/libm/src/Q/nextafterl.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/usr/src/libm/src/Q/nextafterl.c b/usr/src/libm/src/Q/nextafterl.c
new file mode 100644
index 0000000..f1d042f
--- /dev/null
+++ b/usr/src/libm/src/Q/nextafterl.c
@@ -0,0 +1,118 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "@(#)nextafterl.c 1.3 06/01/31 SMI"
+
+#if defined(ELFOBJ)
+#pragma weak nextafterl = __nextafterl
+#endif
+
+#include "libm.h"
+#include <float.h> /* LDBL_MAX, LDBL_MIN */
+
+#if defined(__sparc)
+#define n0 0
+#define n1 1
+#define n2 2
+#define n3 3
+#define X86PDNRM1(x)
+#define INC(px) { \
+ if (++px[n3] == 0) \
+ if (++px[n2] == 0) \
+ if (++px[n1] == 0) \
+ ++px[n0]; \
+ }
+#define DEC(px) { \
+ if (--px[n3] == 0xffffffff) \
+ if (--px[n2] == 0xffffffff) \
+ if (--px[n1] == 0xffffffff) \
+ --px[n0]; \
+ }
+#elif defined(__i386)
+#define n0 2
+#define n1 1
+#define n2 0
+#define n3 0
+/*
+ * if pseudo-denormal, replace by the equivalent normal
+ */
+#define X86PDNRM1(x) if (XBIASED_EXP(x) == 0 && (((int *) &x)[1] & \
+ 0x80000000) != 0) \
+ ((int *) &x)[2] |= 1
+#define INC(px) { \
+ if (++px[n2] == 0) \
+ if ((++px[n1] & ~0x80000000) == 0) \
+ px[n1] = 0x80000000, ++px[n0]; \
+ }
+#define DEC(px) { \
+ if (--px[n2] == 0xffffffff) \
+ if (--px[n1] == 0x7fffffff) \
+ if ((--px[n0] & 0x7fff) != 0) \
+ px[n1] |= 0x80000000; \
+ }
+#endif
+
+long double
+nextafterl(long double x, long double y) {
+ int *px = (int *) &x;
+ int *py = (int *) &y;
+
+ if (x == y)
+ return (y); /* C99 requirement */
+ if (x != x || y != y)
+ return (x * y);
+
+ if (ISZEROL(x)) { /* x == 0.0 */
+ px[n0] = py[n0] & XSGNMSK;
+ px[n1] = px[n2] = 0;
+ px[n3] = 1;
+ } else {
+ X86PDNRM1(x);
+ if ((px[n0] & XSGNMSK) == 0) { /* x > 0.0 */
+ if (x > y) /* x > y */
+ DEC(px)
+ else
+ INC(px)
+ } else {
+ if (x < y) /* x < y */
+ DEC(px)
+ else
+ INC(px)
+ }
+ }
+#ifndef lint
+ {
+ volatile long double dummy;
+ int k = XBIASED_EXP(x);
+
+ if (k == 0)
+ dummy = LDBL_MIN * copysignl(LDBL_MIN, x);
+ else if (k == 0x7fff)
+ dummy = LDBL_MAX * copysignl(LDBL_MAX, x);
+ }
+#endif
+ return (x);
+}