Seen on intel architectures (i686, x86_64). Run following example code: program test complex cres1, cres2, ivc parameter(ivc = (0,1)) const= 0 fact = 0.5 cres1 = csqrt(const + ivc*fact) cres2 = csqrt(const - ivc*fact) print*,'cres1=',cres1, 'cres2=',cres2 const= 1.e-30 cres1 = csqrt(const + ivc*fact) cres2 = csqrt(const - ivc*fact) print*,'cres1=',cres1, 'cres2=',cres2 stop end The result is: cres1= ( 0.5000000 , 0.5000000 ) cres2= (-0.5000000 , 0.5000000 ) cres1= ( 0.5000000 , 0.5000000 ) cres2= ( 0.5000000 ,-0.5000000 ) The first line shows the wrong result, the second is that what one expects. The compiler used it taken from gcc SVN. gfortran -v gives: gcc version 4.1.0 20051118 (experimental)
This bug is in glibc (same code on non-glibc platform, such as sparc-solaris, will give the right answer). It was reported in glibc bugzilla as #1466 (http://sources.redhat.com/bugzilla/show_bug.cgi?id=1466), and is now fixed in glibc CVS. Perhaps we need to workaround that bug somewhere. Opinions, please!
Subject: Re: sqrt, csqrt may give a wrong result if real part of compex argument is zero fxcoudert at gcc dot gnu dot org wrote: > ------- Comment #1 from fxcoudert at gcc dot gnu dot org 2005-11-24 13:05 ------- > This bug is in glibc (same code on non-glibc platform, such as sparc-solaris, > will give the right answer). It was reported in glibc bugzilla as #1466 > (http://sources.redhat.com/bugzilla/show_bug.cgi?id=1466), and is now fixed in > glibc CVS. > > Perhaps we need to workaround that bug somewhere. Opinions, please! > > How long before next glibc release? This problem could be painful for folks that are using gfortran for real world applications who are not aware. Maybe we need to add an errata file to the tree and add a message at the end of configure to remind people to read the errata file. This would go for all of gcc, not just gfortran. Jerry
This is a dup of bug 24313. Gfortran cannot fix a glibc bug. We don't know when glibc is going to be released (also maybe if you complain to the distro you use they will release a newer glibc with the fix). *** This bug has been marked as a duplicate of 24313 ***
c99_functions.c contains implementations of csqrt[fl], which are the fixed glibc routines. We can remove the "#if !defined(HAVE_CSQRTF)" and simply have gfortran use its own versions.
(In reply to comment #4) > c99_functions.c contains implementations of csqrt[fl], > which are the fixed glibc routines. We can remove > the "#if !defined(HAVE_CSQRTF)" and simply have gfortran > use its own versions. For only targets which have a broken csqrtf yes. Please don't do it all the time.
Subject: Re: sqrt, csqrt may give a wrong result if real part of compex argument is zero On Thu, Nov 24, 2005 at 05:05:12PM -0000, pinskia at gcc dot gnu dot org wrote: > > (In reply to comment #4) > > c99_functions.c contains implementations of csqrt[fl], > > which are the fixed glibc routines. We can remove > > the "#if !defined(HAVE_CSQRTF)" and simply have gfortran > > use its own versions. > > For only targets which have a broken csqrtf yes. Please don't do it all the > time. > I've never used glibc. Does it define a _GLIBC_VERSION_MAJOR and _GLIBC_VERSION_MINOR? We could do #if !defined(HAVE_CSQRTF) || (xx_MAJOR < 42 & xx_MINOR < 42)
(In reply to comment #6) > Subject: Re: sqrt, csqrt may give a wrong result if real part of compex > argument is zero > > On Thu, Nov 24, 2005 at 05:05:12PM -0000, pinskia at gcc dot gnu dot org wrote: > > > > (In reply to comment #4) > > > c99_functions.c contains implementations of csqrt[fl], > > > which are the fixed glibc routines. We can remove > > > the "#if !defined(HAVE_CSQRTF)" and simply have gfortran > > > use its own versions. > > > > For only targets which have a broken csqrtf yes. Please don't do it all the > > time. > > > > I've never used glibc. Does it define a _GLIBC_VERSION_MAJOR > and _GLIBC_VERSION_MINOR? We could do > > #if !defined(HAVE_CSQRTF) || (xx_MAJOR < 42 & xx_MINOR < 42) > Dont rely on the glibc version. The better way should be to use libgfortran/configure for csqrt, csqrtf, csqrtl to check them and setting HAVE_CSQRT, HAVE_CSQRTF, HAVE_CSQRTL if the checks will not fail.
Subject: Re: sqrt, csqrt may give a wrong result if real part of compex argument is zero On Tue, Nov 29, 2005 at 09:42:05AM -0000, harald dot vogt at desy dot de wrote: > > > Comment #7 from harald dot vogt at desy dot de 2005-11-29 09:42 ------- > > > > I've never used glibc. Does it define a _GLIBC_VERSION_MAJOR > > and _GLIBC_VERSION_MINOR? We could do > > > > #if !defined(HAVE_CSQRTF) || (xx_MAJOR < 42 & xx_MINOR < 42) > > > > Dont rely on the glibc version. The better way should be to use > libgfortran/configure for csqrt, csqrtf, csqrtl to check them and setting > HAVE_CSQRT, HAVE_CSQRTF, HAVE_CSQRTL if the checks will not fail. > Do you have a patch? Because I have no idea want you mean. libgfortran/configurei already checks for the existence of these functions. glibc's are broken in the release, but are fixed in cvs.
(In reply to comment #8) > Subject: Re: csqrtf, csqrt, csqrtl > > Do you have a patch? Because I have no idea want you > mean. libgfortran/configure already checks for the existence > of these functions. glibc's are broken in the release, > but are fixed in cvs. > After patching libgfortran/configure the code of libgfortran/intrinsics/c99_functions.c was used. But this code has still a problem seen with the following fortran code program test complex cres1, cres2 cres1 = -(4,0) cres2 = sqrt(cres1) print*,'cres1=',cres1, 'cres2=',cres2 cres1 = (-4,0) cres2 = sqrt(cres1) print*,'cres1=',cres1, 'cres2=',cres2 end This requires also corrections in libgfortran/intrinsics/c99_functions.c . The patches I have made compared to gcc-rev-107187 from gcc's SVN you will find here: http://www-zeuthen.desy.de/~hvogt/gfortran/configure.ac.diff http://www-zeuthen.desy.de/~hvogt/gfortran/acinclude.m4.diff http://www-zeuthen.desy.de/~hvogt/gfortran/configure.diff http://www-zeuthen.desy.de/~hvogt/gfortran/config.h.in.diff http://www-zeuthen.desy.de/~hvogt/gfortran/c99_functions.c.diff
Subject: Re: sqrt, csqrt may give a wrong result if real part of compex argument is zero On Wed, Nov 30, 2005 at 04:17:01PM -0000, harald dot vogt at desy dot de wrote: > > http://www-zeuthen.desy.de/~hvogt/gfortran/configure.ac.diff > http://www-zeuthen.desy.de/~hvogt/gfortran/acinclude.m4.diff > http://www-zeuthen.desy.de/~hvogt/gfortran/configure.diff > http://www-zeuthen.desy.de/~hvogt/gfortran/config.h.in.diff > http://www-zeuthen.desy.de/~hvogt/gfortran/c99_functions.c.diff > Your patch is incorrect. See page 472 of n1124.pdf. 3 The functions are continuous onto both sides of their branch cuts, taking into account the sign of zero. For example, cqrt(2 +- i0) = +- i sqrt(2). In F.8.2, we find -x <--> 0 - x The expressions -x and 0 - x are not equivalent if x is +0, because -(+0) yields -0, but 0 - (+0) yields +0 (unless rounding is downward). I need to look through the Fortran standard to see what it does with signed zero.
Subject: Re: sqrt, csqrt may give a wrong result if real part of compex argument is zero On Wed, Nov 30, 2005 at 10:38:13AM -0800, Steve Kargl wrote: > > Your patch is incorrect. See page 472 of n1124.pdf. > > 3 The functions are continuous onto both sides of their branch > cuts, taking into account the sign of zero. For example, > cqrt(2 +- i0) = +- i sqrt(2). > > In F.8.2, we find > > -x <--> 0 - x The expressions -x and 0 - x are not equivalent if x > is +0, because -(+0) yields -0, but 0 - (+0) yields > +0 (unless rounding is downward). > > I need to look through the Fortran standard to see what it does > with signed zero. > OK. I found additional info in the Fortran 2003 standard in 1.6.1 (3) If the processor can distinguish between positive and negative real zero, this standard requires different returned values for ATAN2(Y,X) when X < 0 and Y is negative real zero and for LOG(X) and SQRT(X) when X is complex with REAL(X) < 0 and negative zero imaginary part. Now, I need to determine if unary minus of 0 gives a signed zero