diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 2ccb46b02dd1..bb999ece2f0c 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,10 @@ +2007-08-05 Francois-Xavier Coudert + + PR fortran/31202 + * intrinsics/c99_functions.c (roundl): Provide fallback + implementation for systems without ceill. + * c99_protos.h (roundl): Define prototype in all cases. + 2007-08-03 Thomas Koenig PR libfortran/32977 diff --git a/libgfortran/c99_protos.h b/libgfortran/c99_protos.h index c4738db51a0b..e511b687eea3 100644 --- a/libgfortran/c99_protos.h +++ b/libgfortran/c99_protos.h @@ -200,7 +200,7 @@ extern double round(double); extern float roundf(float); #endif -#if !defined(HAVE_ROUNDL) && defined(HAVE_CEILL) +#if !defined(HAVE_ROUNDL) #define HAVE_ROUNDL 1 extern long double roundl(long double); #endif diff --git a/libgfortran/intrinsics/c99_functions.c b/libgfortran/intrinsics/c99_functions.c index e36c5ba73be0..65c284e9b8c4 100644 --- a/libgfortran/intrinsics/c99_functions.c +++ b/libgfortran/intrinsics/c99_functions.c @@ -500,8 +500,9 @@ powf(float x, float y) /* Algorithm by Steven G. Kargl. */ -#if !defined(HAVE_ROUNDL) && defined(HAVE_CEILL) +#if !defined(HAVE_ROUNDL) #define HAVE_ROUNDL 1 +#if defined(HAVE_CEILL) /* Round to nearest integral value. If the argument is halfway between two integral values then round away from zero. */ @@ -527,6 +528,27 @@ roundl(long double x) return (-t); } } +#else + +/* Poor version of roundl for system that don't have ceill. */ +long double +roundl(long double x) +{ + if (x > DBL_MAX || x < -DBL_MAX) + { +#ifdef HAVE_NEXTAFTERL + static long double prechalf = nexafterl (0.5L, LDBL_MAX); +#else + static long double prechalf = 0.5L; +#endif + return (GFC_INTEGER_LARGEST) (x + (x > 0 ? prechalf : -prechalf)); + } + else + /* Use round(). */ + return round((double) x); +} + +#endif #endif #ifndef HAVE_ROUND