[J3] Question on overflow and run-time detection of infinity?
Bill Long
longb at cray.com
Tue Nov 27 12:33:10 EST 2018
> On Nov 27, 2018, at 12:35 AM, Van Snyder via J3 <j3 at mailman.j3-fortran.org> wrote:
>
> On Tue, 2018-11-27 at 11:13 +0900, Malcolm Cohen via J3 wrote:
>> You can see this by the wording which allows
>> IEEE_VALUE(x,IEEE_SIGNALING_NAN) to raise INVALID and have the
>> signalling NaN converted to a quiet NaN.
>
> Since it's OK for a processor to supply a quiet NaN when a signaling NaN
> is requested,
>
> x = IEEE_VALUE(x,IEEE_SIGNALING_NAN)
>
> might not assign a signaling NaN to X. How does one reliably fill a
> real variable (scalar or otherwise) with signaling NaN?
This seems like a reasonable question, since programs often use sNaN to fill in “undefined” variables, to catch later, improper use.
My interpretation of the IEEE_VALUE function has always been that it returns the bitwise representation of the vendor’s version of the specified value for the same kind as the kind of x. It assigned, as in your example, it just stuffs the bits into the variable as long as the variable in the assignment is the same type and kind as the first argument. (As if the result of IEEE_VALUE was type BITS for the previous definition we had for BITS.)
I tried a simple program:
program ieee_constants
use,intrinsic :: ieee_arithmetic
implicit none
integer,parameter :: dp = ieee_selected_real_kind (14,200)
real(dp) :: x
print *, "Value of dp = ", dp
x = ieee_value (x, ieee_signaling_nan)
write (*,"(a,z18.16)") "Signaling NaN: ", x
x = ieee_value (x, ieee_quiet_nan)
write (*,"(a,z18.16)") "Quite NaN: ", x
x = ieee_value (x, ieee_negative_inf)
write (*,"(a,z18.16)") "Negative INF: ", x
x = ieee_value (x, ieee_positive_inf)
write (*,"(a,z18.16)") "Positive INF: ", x
x = ieee_value (x, ieee_negative_zero)
write (*,"(a,z18.16)") "Negative Zero: ", x
x = ieee_value (x, ieee_positive_zero)
write (*,"(a,z18.16)") "Positive Zero: ", x
end program ieee_constants
All of the compilers I have access to run the program and produce reasonable output (except gfortran that converts the sNaN to a qNaN):
gfortran:
> srun -n1 ./a.out
Value of dp = 8
Signaling NaN: FFF8000000000000
Quite NaN: FFF8000000000000
Negative INF: FFF0000000000000
Positive INF: 7FF0000000000000
Negative Zero: 8000000000000000
Positive Zero: 0000000000000000
pgi:
> srun -n1 ./a.out
Value of dp = 8
Signaling NaN: 7FF4000000000000
Quite NaN: 7FF8000000000000
Negative INF: FFF0000000000000
Positive INF: 7FF0000000000000
Negative Zero: 8000000000000000
Positive Zero: 0000000000000000
Intel:
> srun -n1 ./a.out
Value of dp = 8
Signaling NaN: 7FF4000000000000
Quite NaN: 7FF8000000000000
Negative INF: FFF0000000000000
Positive INF: 7FF0000000000000
Negative Zero: 8000000000000000
Positive Zero: 0000000000000000
Cray:
> srun -n1 ./a.out
Value of dp = 8
Signaling NaN: 7FF0000000000001
Quite NaN: 7FF8000000000001
Negative INF: FFF0000000000000
Positive INF: 7FF0000000000000
Negative Zero: 8000000000000000
Positive Zero: 0000000000000000
In this group, gfortran is only one with the conversion issue. Maybe it is some legacy x87 stuff still sitting around in gfortran. But, I’m not aware of any other compiler that uses the old x87 stuff anymore. (The target processor in all of the examples above was an intel Xeon.)
Cheers,
Bill
>
Bill Long longb at cray.com
Principal Engineer, Fortran Technical Support & voice: 651-605-9024
Bioinformatics Software Development fax: 651-605-9143
Cray Inc./ 2131 Lindau Lane/ Suite 1000/ Bloomington, MN 55425
More information about the J3
mailing list