diff options
author | Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> | 2007-08-03 21:26:10 +0000 |
---|---|---|
committer | François-Xavier Coudert <fxcoudert@gcc.gnu.org> | 2007-08-03 21:26:10 +0000 |
commit | 94f548c244426f45bab1ae19d3359aa2b651dce0 (patch) | |
tree | b3c3360111641d52b502bddd36c0a4ce24d565cf /libgfortran/intrinsics/c99_functions.c | |
parent | 8db6f5454c392b098080e297de645be106d621af (diff) | |
download | gcc-94f548c244426f45bab1ae19d3359aa2b651dce0.zip gcc-94f548c244426f45bab1ae19d3359aa2b651dce0.tar.gz gcc-94f548c244426f45bab1ae19d3359aa2b651dce0.tar.bz2 |
re PR fortran/31202 (Incorrect rounding generated for NINT)
PR fortran/31202
* f95-lang.c (gfc_init_builtin_functions): Defin builtins for
lround{f,,l} and llround{f,,l}.
* trans-intrinsic.c (build_fix_expr): Generate calls to the
{l,}round{f,,l} functions.
* intrinsics/c99_functions.c (roundl,lroundf,lround,lroundl,
llroundf,llround,llroundl): New functions.
* c99_protos.h (roundl,lroundf,lround,lroundl,llroundf,llround,
llroundl): New prototypes.
* configure.ac: Check for lroundf, lround, lroundl, llroundf,
llround and llroundl.
* configure: Regenerate.
* Makefile.in: Regenerate.
* config.h.in: Regenerate.
* gfortran.dg/nint_2.f90: New test.
From-SVN: r127185
Diffstat (limited to 'libgfortran/intrinsics/c99_functions.c')
-rw-r--r-- | libgfortran/intrinsics/c99_functions.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/libgfortran/intrinsics/c99_functions.c b/libgfortran/intrinsics/c99_functions.c index 8b82ae3..e36c5ba 100644 --- a/libgfortran/intrinsics/c99_functions.c +++ b/libgfortran/intrinsics/c99_functions.c @@ -500,6 +500,35 @@ powf(float x, float y) /* Algorithm by Steven G. Kargl. */ +#if !defined(HAVE_ROUNDL) && defined(HAVE_CEILL) +#define HAVE_ROUNDL 1 +/* Round to nearest integral value. If the argument is halfway between two + integral values then round away from zero. */ + +long double +roundl(long double x) +{ + long double t; + if (!isfinite (x)) + return (x); + + if (x >= 0.0) + { + t = ceill(x); + if (t - x > 0.5) + t -= 1.0; + return (t); + } + else + { + t = ceill(-x); + if (t + x > 0.5) + t -= 1.0; + return (-t); + } +} +#endif + #ifndef HAVE_ROUND #define HAVE_ROUND 1 /* Round to nearest integral value. If the argument is halfway between two @@ -558,6 +587,64 @@ roundf(float x) } #endif + +/* lround{f,,l} and llround{f,,l} functions. */ + +#if !defined(HAVE_LROUNDF) && defined(HAVE_ROUNDF) +#define HAVE_LROUNDF 1 +long int +lroundf (float x) +{ + return (long int) roundf (x); +} +#endif + +#if !defined(HAVE_LROUND) && defined(HAVE_ROUND) +#define HAVE_LROUND 1 +long int +lround (double x) +{ + return (long int) round (x); +} +#endif + +#if !defined(HAVE_LROUNDL) && defined(HAVE_ROUNDL) +#define HAVE_LROUNDL 1 +long int +lroundl (long double x) +{ + return (long long int) roundl (x); +} +#endif + +#if !defined(HAVE_LLROUNDF) && defined(HAVE_ROUNDF) +#define HAVE_LLROUNDF 1 +long long int +llroundf (float x) +{ + return (long long int) roundf (x); +} +#endif + +#if !defined(HAVE_LLROUND) && defined(HAVE_ROUND) +#define HAVE_LLROUND 1 +long long int +llround (double x) +{ + return (long long int) round (x); +} +#endif + +#if !defined(HAVE_LLROUNDL) && defined(HAVE_ROUNDL) +#define HAVE_LLROUNDL 1 +long long int +llroundl (long double x) +{ + return (long long int) roundl (x); +} +#endif + + #ifndef HAVE_LOG10L #define HAVE_LOG10L 1 /* log10 function for long double variables. The version provided here |