------- Comment #3 from gdsjaar at sandia dot gov 2009-07-07 19:51 ------- Subject: Re: sign intrinsic fails for value of 0.0
kargl at gcc dot gnu dot org wrote: > ------- Comment #2 from kargl at gcc dot gnu dot org 2009-07-07 19:43 ------- > (In reply to comment #0) > >> sahp7641> /var/scratch2/gcc4/bin/gfortran -v >> Using built-in specs. >> Target: x86_64-unknown-linux-gnu >> Configured with: ../gcc-4.4.0/configure --prefix=/var/scratch2/gcc4/ >> --enable-languages=c++,c,fortran --with-mpfr=/var/scratch2 >> Thread model: posix >> gcc version 4.4.0 (GCC) >> >> The sign intrinsic gives an incorrect value when the second argument is 0.0: >> >> program main >> val = 0.0 >> test = sign(0.5, val) - sign(0.5, -val) >> >> test2 = mysign(0.5, val) >> if (test .ne. test2) then >> write (*,*) 'fail' >> else >> write (*,*) 'pass' >> end if >> stop >> end >> >> real function mysign(a, b) >> C ...Returns `ABS(A)*s', where s is +1 if `B.GE.0', -1 otherwise. >> if (b .ge. 0) then >> s = 1.0 >> else >> s = -1.0 >> end if >> mysign = abs(a) * s >> return >> end >> >> The function 'mysign' implements the definition of the sign function listed >> at >> http://gcc.gnu.org/onlinedocs/gcc-3.4.6/g77/Sign-Intrinsic.html. >> >> When run with gfortran (versions 4.1.2 and 4.4.0 at least), the executable >> prints 'fail'. When built with g77 or intel fortran, it prints 'pass' as >> expected. >> >> The reason I classified this as a major bug is that old fortran vector codes >> use the following idiom to detect a zero value: >> >> test = sign(0.5, val) + sign(0.5, -val) >> ratio = value2 / (val + test) >> >> If val is zero, then test would be 1.0 and ratio ends up with a defined >> value. >> Later on outside the vector loop, error checking is done to catch the >> potential >> bad values. >> > > If you fix your code you will get the expected result, which is 'fail'. > You get 'fail' with your broken code by accident. > > Also note that the g77 documentation is irrelevant. The Fortran 95 > standard defines the behavior of SIGN(). In particular, see case (iv). > > 13.14.98 SIGN (A, B) > > Description. Absolute value of A times the sign of B. > > Class. Elemental function. > > Arguments. > A shall be of type integer or real. > B shall be of the same type and kind type parameter as A. > > Result Characteristics. Same as A. > > Result Value. > Case (i): If B > 0, the value of the result is |A|. > Case (ii): If B < 0, the value of the result is -|A|. > Case (iii): If B is of type integer and B=0, the value of > the result is |A|. > Case (iv): If B is of type real and is zero, then > (a) If the processor cannot distinguish between positive and > negative real zero, the value of the result is |A|. > > (b) If B is positive real zero, the value of the result > is |A|. > > (c) If B is negative real zero, the value of the result > is -|A|. > > Try adding a few PRINT statements to you code. It may help you > understand the results. > OK, so I should instead be submitting a bug report for intel and g77 and pgi. gfortran is the only correct implementation? > > -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40675