Can the function random_number() generate a NAN in Fortran?
If, for instance, I have a real*8 array called A, and I call function random_number(A) - can any A element (result) be a NAN?
No.
According to the Fortran 2008 Standard, Cl. 13.7.135 "RANDOM NUMBER (HARVEST)":
Argument. HARVEST shall be of type real. It is an INTENT (OUT) argument. It may be a scalar or an array.
It is assigned pseudorandom numbers from the uniform distribution in the interval 0 ≤ x < 1.
Related
In Fortran, are these two methods for initializing a parameter array identical? If not, what is the meaning of dimension(*)?
integer, parameter, dimension(2) :: x = [1,2]
vs
integer, parameter, dimension(*) :: x = [1,2]
The effect of both declarations is the same: a rank-1 named constant array of shape [2] with the obvious values.
Using dimension(*) makes the array implied shape rather than explicit shape: the named constant is of shape implied by the constant expression.
Which is better? Well, implied shape is not supported by all compilers (being a Fortran 2008 feature), but it saves worrying about writing shape twice.
Does the following code conform to the Fortran 90 standard?
integer, pointer :: pa ! global
...
recursive subroutine foo(a)
integer, target, intent(in) :: a
if (a > 10) then
return
endif
if (associated(pa)) then
pa = 123
endif
pa => a
call foo(a + 1)
! use a
end subroutine foo
Variable a is declared with intent(in), which according to the Fortran 90 standard, section 5.1.2.3:
specifies that the dummy argument must not be redefined or become undefined during the execution of the procedure
Variable a does not get redefined at the level of recursion of foo(a); instead, we save a pointer to a so we can redefine a on a lower level of recursion.
In other words:
foo(a) ! do not change a, save the pointer to a
foo(a + 1) ! change a, save the pointer to a + 1
foo(a + 1 + 1) ! change a + 1, save the pointer to a + 1 + 1, and so on.
Based on my understanding of the standard, the lifetime of foo(a + 1) is a subset of the lifetime of foo(a), so a should not be changed.
Is it safe for the compiler to assume that foo() has "undefined behaviour" (or Fortran's equivalent of it)?
The answer depends on the value of the actual argument that gets associated with a that the procedure is initially called with, and the association status of pa prior to the first call.
If a is greater than 10, the code is conforming (and not very exciting).
If a is equal to 10, and the pointer association status of pa is undefined, the code is non-conforming. The associated intrinsic requires its actual argument to be defined. If a is equal to 10 and the pointer association status of pa is not undefined, the code is conforming.
If a is less than 10, the code is non-conforming. The INTENT(IN) dummy argument a of the first instance of execution of the procedure is redefined via assignment to the pointer pa during nested execution of the next instance. The rules around INTENT(IN) require that the value of non-pointer dummy arguments not be changed during invocation or execution of the procedure, directly or indirectly.
Beyond diagnostics not relevant here, a conforming Fortran processor can do whatever it wants when executing unconforming code, but conformance versus non-conformance here is an execution time question.
Many corrections to the Fortran 90 standard have been effectively issued over the years, perhaps most of which have been made via edits to subsequent standards. Words in later standards are slightly different, but requirements in this area haven't changed.
I am using intel fortran 2016. I have defined some precision variables as follows:
! definition of single, double and quad precision
integer, parameter :: SINGLE_PRECISION = selected_real_kind(6, 37)
integer, parameter :: DOUBLE_PRECISION = selected_real_kind(15, 307) ! is used as standard precision
integer, parameter :: QUAD_PRECISION = selected_real_kind(33, 4931)
! definition of variable precision for REAL, INTEGER
integer, parameter :: REAL_TYPE = DOUBLE_PRECISION
integer, parameter :: INTEGER_TYPE = 4
I would like to now use these to control the precision of a parameter that gets declared in a subroutine as follows:
SUBROUTINE SKIP(IUNIT,NBYTS)
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
Character c*1
Parameter(n1 = 1024, nT1 = 8*n1)
I tried the following :
Parameter(INTEGER_TYPE)((n1 = 1024, nT1 = 8*n1)
Parameter(INTEGER_TYPE)((n1 = 1024, nT1 = 8*n1, kind = INTEGER_TYPE)
All to no avail. What is the proper way to define parameter precision in Fortran?
Thanks
Note: this is essentially the same as Francescalus' answer, but with some extra fluf.
The issue at hand here is related to the IMPLICIT statement.
The Fortran standard makes the following statements :
5.5 IMPLICIT statement
In a scoping unit, an IMPLICIT statement specifies a type, and
possibly type parameters, for all implicitly typed data entities whose
names begin with one of the letters specified in the statement.
Alternatively, it may indicate that no implicit typing rules are to
apply in a particular scoping unit.
<snip>
In each scoping unit, there is a mapping, which may be null, between
each of the letters A, B, ..., Z and a type (and type parameters).
An IMPLICIT statement specifies the mapping for the letters in its
letter-spec-list. IMPLICIT NONE specifies the null mapping for all
the letters. If a mapping is not specified for a letter, the
default for a program unit or an interface body is default integer if
the letter is I, J, ..., or N and default real otherwise, and the
default for an internal or module procedure is the mapping in the host
scoping unit.
So in short, by default everything is of type default REAL unless it starts with I,J,...,N, then it is of type default INTEGER.
In the example in the question, the variables n1 and nT1 are hence default INTEGER unless specified otherwise. Thus the following might be a solution :
subroutine skip(IUNIT,NBYTS)
implicit double precision (A-H,O-Z)
character c*1
integer(kind=integer_kind), parameter :: n1 = 1024, nT1 = 8*n1
...
end subroutine skip
As a general remark on variable declaration I would like to make the following remarks:
use implicit none as default. It makes debugging easier
avoid star notation, it is not part of the standard for anything but characters, and for characters it is declared obsolescent.
make use of kind parameters declared in the intrinsic module iso_fortran_env
be aware that double precision does not necessarily mean "double precision" in the literal or IEEE sense of the word. It just means, twice the storage of a real and a higher precision than real. (a higher precision could be one-digit).
You can define a parameter of a specific kind with
TYPE, PARAMETER :: name = value_kind
So to define, say, an integer n1 with kind INTEGER_TYPE you do
integer(kind=INTEGER_TYPE), parameter :: n1 = 1024_INTEGER_TYPE
You have an answer which gives the best way to specify the kind of a named constant. You can find much more detail around this question.
However, I'll add some detail about the parameter statement.
The parameter statement makes an object a named constant and specifies its value. It doesn't specify the type or kind of that object.
The example of the question uses implicit typing for n1 and nT1. These are implicitly default integer.
The implicit rule may be changed (I won't show how), but the type may also be given explicitly:
integer(INTEGER_TYPE) n1, nT1
parameter (n1=1024, nT1=8*n1)
Still, the form of the other answer is preferable. And, as noted there, the kind of the literal constants may also be given in the parameter statement if desired.
In Fortran, is the PARAMETER attribute set at runtime or compilation time?
I was wondering if I can pass in the size the of the array at run time and have this set as PARAMETER.
Can this be done? If so, how? If not, why?
Yes, as repeatedly answered, a named constant (an object with the parameter attribute) must have its initial value "known at compile time". However, as you talk about the size of arrays I'll note something else.
When declaring the shape of an array there are many times when the bounds needn't be given by constant expressions (of which a simple named constant is one example). So, in the main program or a module
implicit none
...
integer, dimension(n) :: array ! Not allowed unless n is a named constant.
end program
the n must be a constant. In many other contexts, though, n need only be a specification expression.
implicit none
integer n
read(*,*) n
block
! n is valid specification expression in the block construct
integer, dimension(n) :: array1
call hello(n)
end block
contains
subroutine hello(n)
integer, intent(in) :: n ! Again, n is a specification expression.
integer, dimension(2*n) :: array2
end subroutine
end program
That is, array1 and array2 are explicit shape automatic objects. For many purposes one doesn't really need a named constant.
Beyond the array size, the following is certainly not allowed, though.
implicit none
integer n, m
read(*,*) n, m
block
! n and m are specifications expression in the block construct
integer(kind=m), dimension(n) :: array ! But the kind needs a constant expression.
...
end block
You need dynamic allocation if the size of your array is to be defined as runtime. All parameter (constants) must be defined as compiling time.
The value of a parameter is set at compile time.
A declaration such as
integer, parameter :: number_of_widgets = numwidge
requires that numwidge be known at compile time, indeed known before it is encountered on the rhs of the declaration.
In Fortran, is the PARAMETER attribute set at runtime or compilation time?
I was wondering if I can pass in the size the of the array at run time and have this set as PARAMETER.
Can this be done? If so, how? If not, why?
Yes, as repeatedly answered, a named constant (an object with the parameter attribute) must have its initial value "known at compile time". However, as you talk about the size of arrays I'll note something else.
When declaring the shape of an array there are many times when the bounds needn't be given by constant expressions (of which a simple named constant is one example). So, in the main program or a module
implicit none
...
integer, dimension(n) :: array ! Not allowed unless n is a named constant.
end program
the n must be a constant. In many other contexts, though, n need only be a specification expression.
implicit none
integer n
read(*,*) n
block
! n is valid specification expression in the block construct
integer, dimension(n) :: array1
call hello(n)
end block
contains
subroutine hello(n)
integer, intent(in) :: n ! Again, n is a specification expression.
integer, dimension(2*n) :: array2
end subroutine
end program
That is, array1 and array2 are explicit shape automatic objects. For many purposes one doesn't really need a named constant.
Beyond the array size, the following is certainly not allowed, though.
implicit none
integer n, m
read(*,*) n, m
block
! n and m are specifications expression in the block construct
integer(kind=m), dimension(n) :: array ! But the kind needs a constant expression.
...
end block
You need dynamic allocation if the size of your array is to be defined as runtime. All parameter (constants) must be defined as compiling time.
The value of a parameter is set at compile time.
A declaration such as
integer, parameter :: number_of_widgets = numwidge
requires that numwidge be known at compile time, indeed known before it is encountered on the rhs of the declaration.