This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
[PATCH] Fix round/roundf in intrinsics/c99_functions.c
- From: "John David Anglin" <dave at hiauly1 dot hia dot nrc dot ca>
- To: gcc-patches at gcc dot gnu dot org, fortran at gcc dot gnu dot org
- Date: Mon, 29 Dec 2008 12:08:56 -0500 (EST)
- Subject: [PATCH] Fix round/roundf in intrinsics/c99_functions.c
This patch fixes the failure of nint_2.f90 on hppa*-*-hpux11*.
The problem was traced to a IEEE rounding issue in the statement
"if (t - x > 0.5)".
I proposed revising the if statements to avoid the rounding problem.
Steve Kargl then pointed me to the fix used on FreeBSD.
http://www.freebsd.org/cgi/cvsweb.cgi/src/lib/msun/src/s_roundf.c
This gives details on the rounding issues present in this function.
The FreeBSD change has had three years of testing. Initially the
implementations for FreeBSD Sun and c99_functions.c were identical.
Below is the FreeBSD version of the fix. I have tested that this
change fixes the PR with no new regressions on hppa2.0w-hp-hpux11.11
and hppa64-hp-hpux11.11.
Ok?
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6602)
2008-12-29 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR fortran/33595
* intrinsics/c99_functions.c (round): Use floor instead of ceil.
Revise checks to round up.
(roundf): Likewise.
Index: intrinsics/c99_functions.c
===================================================================
--- intrinsics/c99_functions.c (revision 142935)
+++ intrinsics/c99_functions.c (working copy)
@@ -569,16 +569,16 @@
if (x >= 0.0)
{
- t = ceil(x);
- if (t - x > 0.5)
- t -= 1.0;
+ t = floor(x);
+ if (t - x <= -0.5)
+ t += 1.0;
return (t);
}
else
{
- t = ceil(-x);
- if (t + x > 0.5)
- t -= 1.0;
+ t = floor(-x);
+ if (t + x <= -0.5)
+ t += 1.0;
return (-t);
}
}
@@ -598,16 +598,16 @@
if (x >= 0.0)
{
- t = ceilf(x);
- if (t - x > 0.5)
- t -= 1.0;
+ t = floorf(x);
+ if (t - x <= -0.5)
+ t += 1.0;
return (t);
}
else
{
- t = ceilf(-x);
- if (t + x > 0.5)
- t -= 1.0;
+ t = floorf(-x);
+ if (t + x <= -0.5)
+ t += 1.0;
return (-t);
}
}