Bug 25017 - sqrt, csqrt may give a wrong result if real part of compex argument is zero
Summary: sqrt, csqrt may give a wrong result if real part of compex argument is zero
Status: RESOLVED DUPLICATE of bug 24313
Alias: None
Product: gcc
Classification: Unclassified
Component: libfortran (show other bugs)
Version: 4.1.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-11-24 12:00 UTC by Harald Vogt
Modified: 2005-11-30 16:17 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Harald Vogt 2005-11-24 12:00:28 UTC
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)
Comment 1 Francois-Xavier Coudert 2005-11-24 13:05:07 UTC
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!
Comment 2 Jerry DeLisle 2005-11-24 16:33:55 UTC
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
Comment 3 Andrew Pinski 2005-11-24 16:41:56 UTC
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 ***
Comment 4 kargls 2005-11-24 17:03:32 UTC
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.
Comment 5 Andrew Pinski 2005-11-24 17:05:12 UTC
(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.
Comment 6 Steve Kargl 2005-11-24 17:22:51 UTC
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)

Comment 7 Harald Vogt 2005-11-29 09:42:04 UTC
(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.
Comment 8 Steve Kargl 2005-11-29 12:47:34 UTC
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.

Comment 9 Harald Vogt 2005-11-30 16:17:01 UTC
(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
Comment 10 Steve Kargl 2005-11-30 18:38:21 UTC
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.

Comment 11 Steve Kargl 2005-11-30 19:24:58 UTC
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