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

Reply via email to