summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authordas <das@FreeBSD.org>2007-01-07 07:54:21 +0000
committerdas <das@FreeBSD.org>2007-01-07 07:54:21 +0000
commit3ef4cfecda8155c7c262ddbc3262504420742727 (patch)
tree3a5584933e4e2455c85c5463bf7832cadd314e59 /lib
parent57699b6f9c0b5672956b001a93bf64eaf7eaa325 (diff)
downloadFreeBSD-src-3ef4cfecda8155c7c262ddbc3262504420742727.zip
FreeBSD-src-3ef4cfecda8155c7c262ddbc3262504420742727.tar.gz
Implement modfl().
Diffstat (limited to 'lib')
-rw-r--r--lib/msun/Makefile2
-rw-r--r--lib/msun/Symbol.map1
-rw-r--r--lib/msun/src/math.h2
-rw-r--r--lib/msun/src/s_modfl.c101
4 files changed, 104 insertions, 2 deletions
diff --git a/lib/msun/Makefile b/lib/msun/Makefile
index de8a54e..41fbfe0 100644
--- a/lib/msun/Makefile
+++ b/lib/msun/Makefile
@@ -69,7 +69,7 @@ SYMBOL_MAPS= ${SYM_MAPS}
.endif
# C99 long double functions
-COMMON_SRCS+= s_copysignl.c s_fabsl.c
+COMMON_SRCS+= s_copysignl.c s_fabsl.c s_modfl.c
.if ${LDBL_PREC} != 53
# If long double != double use these; otherwise, we alias the double versions.
COMMON_SRCS+= s_fmal.c s_frexpl.c s_nextafterl.c s_nexttoward.c s_scalbnl.c
diff --git a/lib/msun/Symbol.map b/lib/msun/Symbol.map
index 0b9a6a9..0fed5a9 100644
--- a/lib/msun/Symbol.map
+++ b/lib/msun/Symbol.map
@@ -134,6 +134,7 @@ FBSD_1.0 {
lroundf;
lroundl;
modff;
+ modfl;
nearbyint;
nearbyintf;
nextafter;
diff --git a/lib/msun/src/math.h b/lib/msun/src/math.h
index ba918a3..a5d16c5 100644
--- a/lib/msun/src/math.h
+++ b/lib/msun/src/math.h
@@ -439,8 +439,8 @@ long double logl(long double);
long lrintl(long double);
#endif
long lroundl(long double);
-#if 0
long double modfl(long double, long double *); /* fundamentally !__pure2 */
+#if 0
long double nanl(const char *) __pure2;
long double nearbyintl(long double);
#endif
diff --git a/lib/msun/src/s_modfl.c b/lib/msun/src/s_modfl.c
new file mode 100644
index 0000000..3dcdf86
--- /dev/null
+++ b/lib/msun/src/s_modfl.c
@@ -0,0 +1,101 @@
+/*-
+ * Copyright (c) 2007 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Derived from s_modf.c, which has the following Copyright:
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ *
+ * $FreeBSD$
+ */
+
+#include <float.h>
+#include <math.h>
+#include <sys/types.h>
+
+#include "fpmath.h"
+
+#if LDBL_MANL_SIZE > 32
+#define MASK ((uint64_t)-1)
+#else
+#define MASK ((uint32_t)-1)
+#endif
+/* Return the last n bits of a word, representing the fractional part. */
+#define GETFRAC(bits, n) ((bits) & ~(MASK << (n)))
+/* The number of fraction bits in manh, not counting the integer bit */
+#define HIBITS (LDBL_MANT_DIG - LDBL_MANL_SIZE)
+
+static const long double zero[] = { 0.0L, -0.0L };
+
+long double
+modfl(long double x, long double *iptr)
+{
+ union IEEEl2bits ux;
+ int e;
+
+ ux.e = x;
+ e = ux.bits.exp - LDBL_MAX_EXP + 1;
+ if (e < HIBITS) { /* Integer part is in manh. */
+ if (e < 0) { /* |x|<1 */
+ *iptr = zero[ux.bits.sign];
+ return (x);
+ } else {
+ if ((GETFRAC(ux.bits.manh, HIBITS - 1 - e) |
+ ux.bits.manl) == 0) { /* X is an integer. */
+ *iptr = x;
+ return (zero[ux.bits.sign]);
+ } else {
+ /* Clear all but the top e+1 bits. */
+ ux.bits.manh >>= HIBITS - 1 - e;
+ ux.bits.manh <<= HIBITS - 1 - e;
+ ux.bits.manl = 0;
+ *iptr = ux.e;
+ return (x - ux.e);
+ }
+ }
+ } else if (e >= LDBL_MANT_DIG - 1) { /* x has no fraction part. */
+ *iptr = x;
+ if (x != x) /* Handle NaNs. */
+ return (x);
+ return (zero[ux.bits.sign]);
+ } else { /* Fraction part is in manl. */
+ if (GETFRAC(ux.bits.manl, LDBL_MANT_DIG - 1 - e) == 0) {
+ /* x is integral. */
+ *iptr = x;
+ return (zero[ux.bits.sign]);
+ } else {
+ /* Clear all but the top e+1 bits. */
+ ux.bits.manl >>= LDBL_MANT_DIG - 1 - e;
+ ux.bits.manl <<= LDBL_MANT_DIG - 1 - e;
+ *iptr = ux.e;
+ return (x - ux.e);
+ }
+ }
+}
OpenPOWER on IntegriCloud