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

Reply via email to