- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Is there a FINDLOC() equivalent that can be used for IEEE NAN values? It is my understanding I cannot use FINDLOC with IEEE_VALUE( 1,0, IEEE_QUIET_NAN ), because the IEEE NAN values (signaling or quiet) don't equal anything, "including itself".
I can obviously just put in a DO loop across the array and check for IEEE_IS_NAN, but I'm assuming (possibly erroneously?) that FINDLOC() has a more efficient implementation under the hood.
Link Copied
- « Previous
-
- 1
- 2
- Next »
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I do not think there is a standard feature for achieving an initialisation to NaN within the source code. Instead you will have to rely on the compiler offering options for this. Both gfortran and Intel Fortran have such options, as I am sure, have others.
I experimented with the IEEE function ieee_value, but you cannot use that in initialisation expressions. Oddly enough, the program I used for this experimentation causes an ICE in Intel Fortran 2018 and in oneAPI Intel Fortran:
program init_nan
use, intrinsic :: ieee_arithmetic
real, parameter :: qnan = ieee_value(x,ieee_quiet_nan) !<== Here the ICE happens
type mytype
real :: x = qnan !ieee_value(x,ieee_quiet_nan)
end type
type(mytype) :: y
!y%x = ieee_value(x,ieee_quiet_nan)
write(*,*) y
end program init_nan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In @Arjen_Markus did you need to declare the X for creating the IEEE number
This works
program Console11
use Base
use, intrinsic :: ieee_arithmetic
implicit none
real X1
logical yes
real(kind=dp) qnan
real(kind=dp) T
TYPE, BIND(C) :: FOO_PACKET
REAL(KIND=dp) :: X
REAL(KIND=dp) :: Y
real(KIND=dp) :: Z
END TYPE
integer i
Type(FOO_PACKET) :: P1
DATA i/Z'FFFFFFFF'/
qnan = IEEE_VALUE(T,ieee_quiet_nan) !<== Here the ICE happens
P1%Z = qnan
yes = .false.
X1 = 1.0
! Variables
! Body of Console11
print *, 'Hello World'
yes = ISNAN(X1)
print *,yes
yes = ISNAN(P1%X)
print *,yes
yes = ISNAN(P1%Z)
print *,yes
end program Console11
But in the end you could do the same thing with a Logical variable in the type and set it equal to false on creation and positive once valued. its just a semaphore flag.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Oh, dear, I forgot the "x" argument indeed. But apparently, you cannot use the standard function ieee_value in initialisation expressions (this is a complicated area :)). And the function isnan is not part of the standard.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Observation:
You would not be a regular writer on this board if you did not push the Fortran boundaries.
We are the Federales, do we care about stinking standards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
initialize with ieee -- I tried a lot of combinations IFORT does not allow it that I could find.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I too had thought that one could use IEEE_VALUE in a constant expression, but no - only "Transformational" intrinsics from IEEE_ARITHMETIC and IEEE_EXCEPTIONS can be used, and that limits you to IEEE_SELECTED_REAL_KIND. (I don't pretend to be an expert on the IEEE modules.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Indeed, gfortran complains about this as well.
By the way, Intel Fortran 2018 and oneAPI give a strange message about a variant of the program I posted before:
init_nan.f90(14): error #6959: The array constructor must be a constant. [IEEE_VALUE]
real :: x = ieee_value(x,ieee_quiet_nan)
--------------------^
compilation aborted for init_nan.f90 (code 1)
The program in question:
program init_nan
use, intrinsic :: ieee_arithmetic
type mytype
real :: x = ieee_value(x,ieee_quiet_nan)
end type
type(mytype) :: y
write(*,*) y
end program init_nan
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A work around:
subroutine init_nan
!>> use, intrinsic :: ieee_arithmetic
real, parameter :: IEEE754_SP_QNAN = Z'7FFFFFFF'
real(8), parameter :: IEEE754_DP_QNAN = Z'7FFFFFFFFFFFFFFF'
!>> real, parameter :: qnan = ieee_value(x,ieee_quiet_nan) !<== Here the ICE happens
real, parameter :: qnan = IEEE754_SP_QNAN
type mytype
real :: x = qnan !ieee_value(x,ieee_quiet_nan)
end type
type(mytype) :: y
!y%x = ieee_value(x,ieee_quiet_nan)
write(*,*) y
end subroutine init_nan
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
! Console11.f90
!
! FUNCTIONS:
! Console11 - Entry point of console application.
!
!****************************************************************************
!
! PROGRAM: Console11
!
! PURPOSE: Entry point for the console application.
!
!****************************************************************************
program Console11
use Base
use, intrinsic :: ieee_arithmetic
implicit none
real X1
logical yes
real(kind=dp) qnan
real(kind=dp) T
TYPE, BIND(C) :: FOO_PACKET
REAL(KIND=dp) :: X
REAL(KIND=dp) :: Y
real(KIND=dp) :: Z
END TYPE
integer i
Type(FOO_PACKET) :: P1
DATA i/Z'FFFFFFFF'/
qnan = IEEE_VALUE(T,ieee_quiet_nan) !<== Here the ICE happens
P1%Z = qnan
yes = .false.
X1 = 1.0
! Variables
! Body of Console11
print *, 'Hello World'
yes = ISNAN(X1)
print *,yes
yes = ISNAN(P1%X)
print *,yes
yes = ISNAN(P1%Z)
print *,yes
call init_nan()
end program Console11
subroutine init_nan
!>> use, intrinsic :: ieee_arithmetic
real, parameter :: IEEE754_SP_QNAN = Z'7FFFFFFF'
real(8), parameter :: IEEE754_DP_QNAN = Z'7FFFFFFFFFFFFFFF'
!>> real, parameter :: qnan = ieee_value(x,ieee_quiet_nan) !<== Here the ICE happens
real, parameter :: qnan = IEEE754_SP_QNAN
type mytype
real :: x = qnan !ieee_value(x,ieee_quiet_nan)
end type
type(mytype) :: y
write(*,*)qnan
print *, 'Hello World'
!y%x = ieee_value(x,ieee_quiet_nan)
write(*,*) y
end subroutine init_nan
In Visual Studio on the autos and locals one cannot see a value for qnan -- I had never noticed that parameters do not show up - interesting,
Observation:
Opera does not color code the Fortran on these posts, whereas IE makes it look like Visual Studio
IE -- the program that has a few features that make it worth keeping around - often like an oft loved board.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
John there is an compiler option you need to set to show debug parameters
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Philosophically, and irrespective of the language after all this is just an intermediate translation into Machine Language and Backus was really with Fortran taking the first steps to what ultimately must be the universal compiler, BNF style.
The use of a NAN is just a logical flag in this context for this problem and a defined types with a logical flag recording set of the variables would be cleaner and simpler to understand for future readers of the program.
@jimdempseyatthecove solution requires that the nan is dependent on the architecture whether 32 or 64 bits, what happens at 128 bits. If we can think about it humans will invent it.
The recent code that some one wanted to get working on this site, had program defining dependencies scattered all over the program. This is ok for a single developer with a good memory, but it is poor real practice.
that is what I like about this site. Great people, interesting conversation and high controversy over simple topics.
Although whoever invented counting arrays from 0 has a special place in the seventh level of Dante's world.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>...solution requires that the nan is dependent on the architecture whether 32 or 64 bits, what happens at 128 bits.
The IEEE 754 standard specifies a binary128 as having:
- Sign bit: 1 bit
- Exponent width: 15 bits
- Significand precision: 113 bits (112 explicitly stored)
The IEEE 754 standard specifies a binary16 as having the following format:
- Sign bit: 1 bit
- Exponent width: 5 bits
- Significand precision: 11 bits (10 explicitly stored)
ergo
real(16), parameter :: IEEE754_QP_QNAN = Z'7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF'
! and if and when half precision supported...
real(2), parameter :: IEEE754_HP_QNAN = Z'7FFF'
Jim Dempsey
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- « Previous
-
- 1
- 2
- Next »