Variables, Data Types & Kinds

⚠️ Initializing in a declaration (integer :: count = 0) inside a procedure gives the variable the implicit save attribute (it keeps its value between calls) — a classic surprise.

4.1 Intrinsic types

integer:: n 3.14, 1.0e-3, 2. double precision (legacy) double precision:: d complex:: z logical:: flag .true., .false. character(len=20):: name "text", 'text'

⚠️ Initializing in a declaration (integer :: count = 0) inside a procedure gives the variable the implicit save attribute (it keeps its value between calls) — a classic surprise.

program types
  implicit none
  integer :: count = 0
  real :: temperature
  complex :: z
  logical :: done
  character(len=30) :: city
  character(len=:), allocatable :: message      ! deferred-length string

  temperature = 21.5
  z = cmplx(1.0, 2.0)
  done = .false.
  city = "Oslo"
  message = "Hello, " // trim(city)
  print *, count, temperature, z, done, message
end program types

4.2 Kinds — controlling precision portably

Never assume real is 32-bit or rely on real*8. Use kind parameters:

Alternative: selected_real_kind / selected_int_kind:

Best practice: define kinds once in a module (use precision, only: dp) and suffix literals: 0.1_dp. Writing real(dp) :: a = 0.1 gives only single-precision accuracy because 0.1 is a default real literal!

program kinds
  use, intrinsic :: iso_fortran_env, only: int32, int64, real32, real64, real128
  implicit none
  integer(int64) :: big = 9223372036854775807_int64
  real(real64)   :: x = 1.0_real64 / 3.0_real64
  real(real32)   :: y = 1.0_real32 / 3.0_real32
  print *, x, y, big
  print *, "digits:", precision(x), precision(y), " range:", range(x)
end program kinds
integer, parameter :: dp = selected_real_kind(p=15, r=307)   ! at least 15 digits, exponent range 307
integer, parameter :: sp = selected_real_kind(6, 37)
integer, parameter :: i8 = selected_int_kind(18)
real(dp) :: a = 1.0_dp

4.3 Kind inquiry functions

kind(1.0), kind(1.0d0), huge(1), tiny(1.0_dp), epsilon(1.0_dp), digits(x), precision(x),
range(x), radix(x), maxexponent(x), minexponent(x), storage_size(x), bit_size(1)

4.4 Type conversion

Mixed-mode arithmetic converts to the "higher" type: integer → real → complex; beware integer division: 1/2 == 0.

real(n, dp)          ! integer → real(dp)
int(3.9)             ! 3 (truncation)
nint(3.5)            ! 4 (nearest integer)
floor(-2.5), ceiling(2.1)
dble(x)              ! legacy → double precision
cmplx(re, im, kind=dp)
logical(flag, kind=1)
achar(65), iachar('A')   ! 'A', 65 (ASCII)