From 94f548c244426f45bab1ae19d3359aa2b651dce0 Mon Sep 17 00:00:00 2001 From: Francois-Xavier Coudert Date: Fri, 3 Aug 2007 21:26:10 +0000 Subject: 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 --- libgfortran/intrinsics/c99_functions.c | 87 ++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) (limited to 'libgfortran/intrinsics') 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 -- cgit v1.1