[Bug fortran/40675] sign intrinsic fails for value of 0.0

kargl at gcc dot gnu dot org gcc-bugzilla@gcc.gnu.org
Tue Jul 7 19:43:00 GMT 2009



------- 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.


-- 

kargl at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|major                       |normal


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40675



More information about the Gcc-bugs mailing list