How to convert from one Fortran integer kind to a smaller one?
I need to convert a parameter from integer(kind=8)
to integer(kind=4)
in Fortran, is there any (simple) way of doing this?
This parameter is an input number, and if this number is greater than 2^31-1 (the limit of a 4-byte integer), the program will always ask for a smaller number (so it can "fit" inside those 4 bytes), so I think that this shouldn't be a problem.
Solution 1:
To create integer of any kind use
result = int(source, kind=result_kind)
so you can do
result = int(source, 4)
source
can be any number, including an integer of any kind.
Note that kind=8
does not mean 8 bytes and kind=4
does not mean 4 bytes. There are compilers which do not have kinds 4 and 8 at all. These numbers are not portable. Do not use them. See Fortran: integer*4 vs integer(4) vs integer(kind=4) for more details.
Solution 2:
As Vladimir F's answer notes, the intrinsic function int
returns an integer value of desired kind int(i,kind=kind)
.
When an expression of a certain kind is required (such as in a procedure argument list) this is quite useful:
call sub_with_int_i1_arg(INT(int_i2, kind=i1))
However, intrinsic assignment to an integer already provides conversion if required:
integer, parameter :: kind1=7, kind2=23
integer(kind1) :: i
integer(kind2) :: j = 85
! The intrinsic assignment
i = j
! is equivalent to
i = INT(j,KIND(i))
! which here is also
i = INT(j,kind1)
end
The intrinsic huge
may be useful in determining whether the range of i
is large enough:
if (ABS(j).le.HUGE(i)) then
i = j
else
error stop "Oh noes :("
end if
As Steve Lionel commented about the draft, Fortran 2018 introduced the intrinsic function out_of_range
which also tests such cases:
if (.not.OUT_OF_RANGE(j,i)) then
i = j
else
error stop "Oh noes :("
end if
However, even in early 2022 it's not wise to rely on implementation of this function.