[Update 20230911: There is a potential solution suggested on GitHub, but it contains non-standard code. Thank you for giving your comments.]
Here is a challenge for those who are interested. It is a true challenge for me, but maybe I have overlooked something and it turns out trivial for you.
Could anyone write five functions is_nan
, is_inf
, is_posinf
, is_neginf
, and is_finite
to test whether each entry of x
and y
in the following code is NaN, Infinity (+ or -), +Infinity, -Infinity, or finite? The functions must work correctly when the WHOLE program is compiled with
gfortran-13 -Ofast
Note that ieee_is_nan
etc. from ieee_arithmetic
do not work under this situation.
Code:
PINF_SP = ieee_value(1.0, ieee_positive_inf)
NINF_SP = ieee_value(1.0, ieee_negative_inf)
QNAN_SP = ieee_value(1.0, ieee_quiet_nan)
SNAN_SP = ieee_value(1.0, ieee_signaling_nan)
PNORMAL_SP = ieee_value(1.0, ieee_positive_normal)
NNORMAL_SP = ieee_value(1.0, ieee_negative_normal)
PDENORMAL_SP = ieee_value(1.0, ieee_positive_denormal)
NDENORMAL_SP = ieee_value(1.0, ieee_negative_denormal)
PZERO_SP = ieee_value(1.0, ieee_positive_zero)
NZERO_SP = ieee_value(1.0, ieee_negative_zero)
PINF_DP = ieee_value(1.0D0, ieee_positive_inf)
NINF_DP = ieee_value(1.0D0, ieee_negative_inf)
QNAN_DP = ieee_value(1.0D0, ieee_quiet_nan)
SNAN_DP = ieee_value(1.0D0, ieee_signaling_nan)
PNORMAL_DP = ieee_value(1.0D0, ieee_positive_normal)
NNORMAL_DP = ieee_value(1.0D0, ieee_negative_normal)
PDENORMAL_DP = ieee_value(1.0D0, ieee_positive_denormal)
NDENORMAL_DP = ieee_value(1.0D0, ieee_negative_denormal)
PZERO_DP = ieee_value(1.0D0, ieee_positive_zero)
NZERO_DP = ieee_value(1.0D0, ieee_negative_zero)
x = [PINF_SP, NINF_SP, &
& QNAN_SP, SNAN_SP, &
& PNORMAL_SP, NNORMAL_SP, &
& PDENORMAL_SP, NDENORMAL_SP, &
& PZERO_SP, NZERO_SP, &
& huge(0.0), -huge(0.0), &
& epsilon(0.0), -epsilon(0.0), &
& tiny(0.0), -tiny(0.0), &
& 0.0, 1.0, -1.0]
y = [PINF_DP, NINF_DP, &
& QNAN_DP, SNAN_DP, &
& PNORMAL_DP, NNORMAL_DP, &
& PDENORMAL_DP, NDENORMAL_DP, &
& PZERO_DP, NZERO_DP, &
& huge(0.0D0), -huge(0.0D0), &
& epsilon(0.0D0), -epsilon(0.0D0), &
& tiny(0.0D0), -tiny(0.0D0), &
& 0.0D0, 1.0D0, -1.0D0]
Motivation: I have a project that provides such functions, which are supposed to work correctly even if compilers are invoked with aggressive optimization flags. They work without any problem with gfortran 9, 10, 11, and 12 (in addition to many other compilers), but fail with gfortran-13. If you are interested, you may clone my project and do
cd test && make gtest
which should fail if your gfortran is gfortran 13. You may also test ifort with make itest
.
Below is the Fortran file that I use to conduct the above-mentioned test. Note that it depends on other files in the project.
Thanks.
N.B.: It is well known why naive testing of Inf and NaN can fail when compilers are invoked with aggressive optimization options. To be clear, the “why” is NOT the topic of this thread. The topic is “how”. Thanks.