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 | |
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')
-rw-r--r-- | lib/msun/Makefile | 11 | ||||
-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 |
10 files changed, 200 insertions, 4 deletions
diff --git a/lib/msun/Makefile b/lib/msun/Makefile index 712f0c2..209ea4e 100644 --- a/lib/msun/Makefile +++ b/lib/msun/Makefile @@ -52,7 +52,7 @@ ARCH_SRCS = s_copysign.S s_copysignf.S ARCH_SUBDIR= i387 ARCH_SRCS = e_acos.S e_asin.S e_atan2.S e_exp.S e_fmod.S e_log.S e_log10.S \ e_remainder.S e_scalb.S e_sqrt.S s_atan.S s_ceil.S s_copysign.S \ - s_cos.S s_finite.S s_floor.S s_logb.S \ + s_cos.S s_finite.S s_floor.S s_llrint.S s_logb.S s_lrint.S \ s_rint.S s_scalbn.S s_significand.S s_sin.S s_tan.S # Broken: # ARCH_SRCS+= s_log1p.S @@ -86,8 +86,9 @@ COMMON_SRCS= b_exp.c b_log.c b_tgamma.c \ s_floor.c s_floorf.c s_fmax.c s_fmaxf.c s_fmaxl.c s_fmin.c \ s_fminf.c s_fminl.c s_frexp.c s_frexpf.c s_ilogb.c s_ilogbf.c \ s_ilogbl.c s_isfinite.c s_isnan.c s_isnormal.c s_ldexpf.c \ - s_lib_version.c s_log1p.c \ - s_log1pf.c s_logb.c s_logbf.c s_matherr.c s_modff.c \ + s_lib_version.c s_llrint.c s_llrintf.c s_llround.c s_llroundf.c \ + s_log1p.c s_log1pf.c s_logb.c s_logbf.c s_lrint.c s_lrintf.c \ + s_lround.c s_lroundf.c s_matherr.c s_modff.c \ s_nearbyint.c s_nextafter.c s_nextafterf.c \ s_rint.c s_rintf.c s_round.c s_roundf.c \ s_scalbln.c s_scalbn.c s_scalbnf.c s_signbit.c \ @@ -132,7 +133,7 @@ INCS= fenv.h math.h MAN= acos.3 acosh.3 asin.3 asinh.3 atan.3 atan2.3 atanh.3 ceil.3 \ cimag.3 cos.3 cosh.3 erf.3 exp.3 fabs.3 fdim.3 feclearexcept.3 \ fegetenv.3 fegetround.3 fenv.3 floor.3 fmax.3 fmod.3 hypot.3 ieee.3 \ - ieee_test.3 j0.3 lgamma.3 math.3 rint.3 round.3 \ + ieee_test.3 j0.3 lgamma.3 lrint.3 lround.3 math.3 rint.3 round.3 \ signbit.3 sin.3 sinh.3 sqrt.3 tan.3 tanh.3 trunc.3 MLINKS+=acos.3 acosf.3 @@ -177,6 +178,8 @@ MLINKS+=ieee_test.3 significand.3 ieee_test.3 significandf.3 MLINKS+=j0.3 j1.3 j0.3 jn.3 j0.3 y0.3 j0.3 y1.3 j0.3 y1f.3 j0.3 yn.3 MLINKS+=j0.3 j0f.3 j0.3 j1f.3 j0.3 jnf.3 j0.3 y0f.3 j0.3 ynf.3 MLINKS+=lgamma.3 gamma.3 lgamma.3 gammaf.3 lgamma.3 lgammaf.3 lgamma.3 tgamma.3 +MLINKS+=lrint.3 llrint.3 lrint.3 llrintf.3 lrint.3 lrintf.3 +MLINKS+=lround.3 llround.3 lround.3 llroundf.3 lround.3 lroundf.3 MLINKS+=rint.3 rintf.3 rint.3 nearbyint.3 rint.3 nearbyintf.3 MLINKS+=round.3 roundf.3 MLINKS+=sin.3 sinf.3 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" |