diff options
author | das <das@FreeBSD.org> | 2005-01-11 23:12:55 +0000 |
---|---|---|
committer | das <das@FreeBSD.org> | 2005-01-11 23:12:55 +0000 |
commit | 75bc489b6d03d2c16b15aaef653ed2c8c6a75694 (patch) | |
tree | f42f6e21c95b34f19074c7e2bd39938f6a3f9886 /lib/msun/src | |
parent | 0a78d59d1fb4973a45e66d96381e83171e30f3df (diff) | |
download | FreeBSD-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.h | 8 | ||||
-rw-r--r-- | lib/msun/src/s_llrint.c | 9 | ||||
-rw-r--r-- | lib/msun/src/s_llrintf.c | 9 | ||||
-rw-r--r-- | lib/msun/src/s_llround.c | 11 | ||||
-rw-r--r-- | lib/msun/src/s_llroundf.c | 11 | ||||
-rw-r--r-- | lib/msun/src/s_lrint.c | 58 | ||||
-rw-r--r-- | lib/msun/src/s_lrintf.c | 9 | ||||
-rw-r--r-- | lib/msun/src/s_lround.c | 67 | ||||
-rw-r--r-- | lib/msun/src/s_lroundf.c | 11 |
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" |