This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug testsuite/32057] Random failure on gfortran.dg/secnds.f
- From: "dominiq at lps dot ens dot fr" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 29 May 2007 20:25:10 -0000
- Subject: [Bug testsuite/32057] Random failure on gfortran.dg/secnds.f
- References: <bug-32057-682@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #4 from dominiq at lps dot ens dot fr 2007-05-29 20:25 -------
Following the Steve Kargl's suggestion in
http://gcc.gnu.org/ml/gcc-patches/2007-05/msg01945.html
I have done the following test:
[archimede] test/fortran> cat > sec_prec_1.f90
implicit none
integer j, k, l, m, n
integer i, ifa, ifb, ifc
real a, b, c
i = 0 ; ifa = 0 ; ifb = 0 ; ifc = 0
do m = 0, 23
do l = 0, 59
do k = 0, 59
do j = 0, 999
i = i + 1
a = 3600.0*real(m)+ 60.0*real(l) + real(k) + 0.001*real(j)
b = 0.001*real(j) + real(k) + 60.0*real(l) + 3600.0*real(m)
c = (3600000*m + 60000*l + 1000*k + j)/1000.0
if (b /= c) ifa = ifa + 1
if (a /= c) ifb = ifb + 1
if (a /= b) ifc = ifc + 1
end do
end do
end do
end do
print *, i, ifa, ifb, ifc
end
On PPC OSX and AMD64 Linux (with and without -O), I get:
86400000 19312016 17523130 2683738
It seems hard to decide what is the right solution, expect that the same has to
be used in the test cases. On a Pentium Linux, I get the same result if I use
-ffloat-store. Without this flag I get:
86400000 1934 1934 0
without -O and
86400000 86313600 86313600 0
with -O. Since I understand that in the later cases, the right hand side is
computed as real(10), hence a and b are the same after rounding to real(4).
However I don't see why the optimization has such a dramatic effect.
I have also run the following test:
[archimede] test/fortran> cat > sec_prec.f90
integer i, j, k, l, m, n
real a, b, c
k = 59
l = 59
m = 23
do i = 0, 9
a = 86399.0 + 0.001*real(990+i)
b = 0.001*real(990+i) + real(k) + 60.0*real(l) + 3600.0*real(m)
c = (86399990 + i)/1000.0
print '(I3,3(1PG20.10))', i, a, b, c
end do
end
which gives:
0 86399.99219 86399.99219 86399.99219
1 86399.99219 86399.99219 86399.99219
2 86399.99219 86399.99219 86399.99219
3 86399.99219 86399.99219 86399.99219
4 86399.99219 86399.99219 86399.99219
5 86399.99219 86399.99219 86399.99219
6 86399.99219 86400.00000 86400.00000
7 86400.00000 86400.00000 86400.00000
8 86400.00000 86400.00000 86400.00000
9 86400.00000 86400.00000 86400.00000
i.e., the last 3/4 ms gives 86400.0, hence the result of secnds(0.0) is inside
the interval [0.0,86400.0] and not inside [0.0,86400.0[ as I naively expected.
This is the cryptic point (2) in my comment #1.
A side effect is that if your are within this time frame and do
t1=secnds(0.0); t2=secnds(t1)
you get 86400.0 instead of 0.0. A possible solution is to add a
t1=min(86399.996,t1) to force the output in the semiopen interval. With the
reversal of the time computation and putting everything in float, it leads to
the following patch:
--- gcc-4.3-20070525/libgfortran/intrinsics/date_and_time.c Fri Apr 6
18:47:23 2007
+++ gcc-4.3-20070526/libgfortran/intrinsics/date_and_time.c Mon May 28
21:40:46 2007
@@ -341,12 +341,15 @@
free_mem (avalues);
- temp1 = 3600.0 * (GFC_REAL_4)values[4] +
- 60.0 * (GFC_REAL_4)values[5] +
- (GFC_REAL_4)values[6] +
- 0.001 * (GFC_REAL_4)values[7];
- temp2 = fmod (*x, 86400.0);
- temp2 = (temp1 - temp2 >= 0.0) ? temp2 : (temp2 - 86400.0);
+ temp1 = 0.001f * (GFC_REAL_4)values[7] +
+ (GFC_REAL_4)values[6] +
+ 60.0f * (GFC_REAL_4)values[5] +
+ 3600.0f * (GFC_REAL_4)values[4];
+
+ /* Fix the round-off errors for the 3ms before midnight. */
+ temp1= (86399.996f>=temp1)? temp1 : 86399.996f;
+ temp2 = fmod (*x, 86400.0f);
+ temp2 = (temp1 - temp2 >= 0.0f) ? temp2 : (temp2 - 86400.0f);
return temp1 - temp2;
}
I have implemented part of it (without the reversal for temp1) on my last build
on OSX and it seems to work. For the other platforms I rely on binaries, so I
need some outside help to test the patch on them!-)
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32057