summaryrefslogtreecommitdiffstats
path: root/lib/msun/src
diff options
context:
space:
mode:
authordas <das@FreeBSD.org>2005-01-11 23:12:55 +0000
committerdas <das@FreeBSD.org>2005-01-11 23:12:55 +0000
commit75bc489b6d03d2c16b15aaef653ed2c8c6a75694 (patch)
treef42f6e21c95b34f19074c7e2bd39938f6a3f9886 /lib/msun/src
parent0a78d59d1fb4973a45e66d96381e83171e30f3df (diff)
downloadFreeBSD-src-75bc489b6d03d2c16b15aaef653ed2c8c6a75694.zip
FreeBSD-src-75bc489b6d03d2c16b15aaef653ed2c8c6a75694.tar.gz
Add MI implementations of [l]lrint[f]() and [l]lround[f]().
Discussed with: bde
Diffstat (limited to 'lib/msun/src')
-rw-r--r--lib/msun/src/math.h8
-rw-r--r--lib/msun/src/s_llrint.c9
-rw-r--r--lib/msun/src/s_llrintf.c9
-rw-r--r--lib/msun/src/s_llround.c11
-rw-r--r--lib/msun/src/s_llroundf.c11
-rw-r--r--lib/msun/src/s_lrint.c58
-rw-r--r--lib/msun/src/s_lrintf.c9
-rw-r--r--lib/msun/src/s_lround.c67
-rw-r--r--lib/msun/src/s_lroundf.c11
9 files changed, 193 insertions, 0 deletions
diff --git a/lib/msun/src/math.h b/lib/msun/src/math.h
index 7d85545..e5d6c2b 100644
--- a/lib/msun/src/math.h
+++ b/lib/msun/src/math.h
@@ -265,8 +265,12 @@ int ilogb(double);
int (isinf)(double) __pure2;
int (isnan)(double) __pure2;
double lgamma(double);
+long long llrint(double);
+long long llround(double);
double log1p(double) __pure2;
double logb(double) __pure2;
+long lrint(double);
+long lround(double);
double nextafter(double, double);
double remainder(double, double);
double rint(double) __pure2;
@@ -368,6 +372,10 @@ float atanhf(float);
float cbrtf(float) __pure2;
float logbf(float) __pure2;
float copysignf(float, float) __pure2;
+long long llrintf(float);
+long long llroundf(float);
+long lrintf(float);
+long lroundf(float);
float nearbyintf(float) __pure2;
float nextafterf(float, float);
float remainderf(float, float);
diff --git a/lib/msun/src/s_llrint.c b/lib/msun/src/s_llrint.c
new file mode 100644
index 0000000..7c959ec
--- /dev/null
+++ b/lib/msun/src/s_llrint.c
@@ -0,0 +1,9 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define type double
+#define roundit rint
+#define dtype long long
+#define fn llrint
+
+#include "s_lrint.c"
diff --git a/lib/msun/src/s_llrintf.c b/lib/msun/src/s_llrintf.c
new file mode 100644
index 0000000..7ec6015
--- /dev/null
+++ b/lib/msun/src/s_llrintf.c
@@ -0,0 +1,9 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define type float
+#define roundit rintf
+#define dtype long long
+#define fn llrintf
+
+#include "s_lrint.c"
diff --git a/lib/msun/src/s_llround.c b/lib/msun/src/s_llround.c
new file mode 100644
index 0000000..f907c05
--- /dev/null
+++ b/lib/msun/src/s_llround.c
@@ -0,0 +1,11 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define type double
+#define roundit round
+#define dtype long long
+#define DTYPE_MIN LLONG_MIN
+#define DTYPE_MAX LLONG_MAX
+#define fn llround
+
+#include "s_lrint.c"
diff --git a/lib/msun/src/s_llroundf.c b/lib/msun/src/s_llroundf.c
new file mode 100644
index 0000000..78a8feb
--- /dev/null
+++ b/lib/msun/src/s_llroundf.c
@@ -0,0 +1,11 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define type float
+#define roundit roundf
+#define dtype long long
+#define DTYPE_MIN LLONG_MIN
+#define DTYPE_MAX LLONG_MAX
+#define fn llroundf
+
+#include "s_lrint.c"
diff --git a/lib/msun/src/s_lrint.c b/lib/msun/src/s_lrint.c
new file mode 100644
index 0000000..27ff5ff
--- /dev/null
+++ b/lib/msun/src/s_lrint.c
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 2005 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.
+ */
+
+#include <sys/cdefs.h>
+#include <fenv.h>
+#include <math.h>
+
+#ifndef type
+__FBSDID("$FreeBSD$");
+#define type double
+#define roundit rint
+#define dtype long
+#define fn lrint
+#endif
+
+/*
+ * C99 says we should not raise a spurious inexact exception when an
+ * invalid exception is raised. Unfortunately, the set of inputs
+ * that overflows depends on the rounding mode when 'dtype' has more
+ * significant bits than 'type'. Hence, we bend over backwards for the
+ * sake of correctness; an MD implementation could be more efficient.
+ */
+dtype
+fn(type x)
+{
+ fenv_t env;
+ dtype d;
+
+ feholdexcept(&env);
+ d = (dtype)roundit(x);
+ if (fetestexcept(FE_INVALID))
+ feclearexcept(FE_INEXACT);
+ feupdateenv(&env);
+ return (d);
+}
diff --git a/lib/msun/src/s_lrintf.c b/lib/msun/src/s_lrintf.c
new file mode 100644
index 0000000..a757ded
--- /dev/null
+++ b/lib/msun/src/s_lrintf.c
@@ -0,0 +1,9 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define type float
+#define roundit rintf
+#define dtype long
+#define fn lrintf
+
+#include "s_lrint.c"
diff --git a/lib/msun/src/s_lround.c b/lib/msun/src/s_lround.c
new file mode 100644
index 0000000..5101bbb
--- /dev/null
+++ b/lib/msun/src/s_lround.c
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 2005 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.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/limits.h>
+#include <fenv.h>
+#include <math.h>
+
+#ifndef type
+__FBSDID("$FreeBSD$");
+#define type double
+#define roundit round
+#define dtype long
+#define DTYPE_MIN LONG_MIN
+#define DTYPE_MAX LONG_MAX
+#define fn lround
+#endif
+
+/*
+ * If type has more precision than dtype, the endpoints dtype_(min|max) are
+ * of the form xxx.5; they are "out of range" because lround() rounds away
+ * from 0. On the other hand, if type has less precision than dtype, then
+ * all values that are out of range are integral, so we might as well assume
+ * that everything is in range. (The correct condition in this case is
+ * harder to express.) At compile time, INRANGE(x) should reduce to two
+ * floating-point comparisons in the former case, or TRUE otherwise.
+ */
+static const double dtype_min = DTYPE_MIN - 0.5;
+static const double dtype_max = DTYPE_MAX + 0.5;
+#define INRANGE(x) (dtype_max - DTYPE_MAX != 0.5 || \
+ ((x) > dtype_min && (x) < dtype_max))
+
+dtype
+fn(type x)
+{
+
+ if (INRANGE(x)) {
+ x = roundit(x);
+ return ((dtype)x);
+ } else {
+ feraiseexcept(FE_INVALID);
+ return (DTYPE_MAX);
+ }
+}
diff --git a/lib/msun/src/s_lroundf.c b/lib/msun/src/s_lroundf.c
new file mode 100644
index 0000000..6d1d2b3
--- /dev/null
+++ b/lib/msun/src/s_lroundf.c
@@ -0,0 +1,11 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define type float
+#define roundit roundf
+#define dtype long
+#define DTYPE_MIN LONG_MIN
+#define DTYPE_MAX LONG_MAX
+#define fn lroundf
+
+#include "s_lrint.c"
OpenPOWER on IntegriCloud