Beginner

Variables and Types in Fortran

Learn about variables, data types, and type conversions in Fortran with practical Docker-ready examples

Fortran’s type system reflects its origins as a language built for numerical computation. Every variable must be explicitly declared with a type before use (when following the implicit none best practice), and the compiler enforces type safety at compile time. This static, strong typing catches entire categories of bugs before your program ever runs.

Fortran provides a rich set of numeric types — including built-in complex number support, something most languages delegate to libraries. The language also offers fine-grained control over numeric precision through its kind system, which lets you specify exactly how many bytes a number should occupy in memory.

In this tutorial, you’ll learn how to declare variables with all of Fortran’s intrinsic types, use constants with the parameter attribute, control numeric precision with kind specifiers, and convert between types.

Basic Variable Declarations

Fortran declares variables between implicit none and the executable statements. Each declaration specifies the type followed by :: and the variable name.

Create a file named variables.f90:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
program variables
    implicit none

    ! Integer types
    integer :: count
    integer :: year

    ! Real (floating-point) types
    real :: temperature
    real :: pi

    ! Character (string) types
    character(len=20) :: name
    character(len=50) :: greeting

    ! Logical (boolean) type
    logical :: is_valid

    ! Complex number type
    complex :: z

    ! Assign values
    count = 42
    year = 1957
    temperature = 98.6
    pi = 3.14159
    name = "Fortran"
    greeting = "Hello from Fortran!"
    is_valid = .true.
    z = (3.0, 4.0)  ! 3 + 4i

    ! Print all variables
    print *, "count       =", count
    print *, "year        =", year
    print *, "temperature =", temperature
    print *, "pi          =", pi
    print *, "name        = ", trim(name)
    print *, "greeting    = ", trim(greeting)
    print *, "is_valid    =", is_valid
    print *, "complex z   =", z

end program variables

Declaration Rules

  • All declarations must appear before any executable statement — Fortran does not allow declaring variables mid-block.
  • Character variables require a len= specifier. If the assigned string is shorter than len, it gets padded with spaces; trim() removes trailing spaces.
  • Logical literals use .true. and .false. (with the dots).
  • Complex numbers are written as (real_part, imaginary_part).

Constants, Kind Specifiers, and Type Conversions

Fortran’s parameter attribute creates named constants that the compiler can optimize. The kind system lets you control numeric precision — essential for scientific computing where single precision may not be accurate enough.

Create a file named variables_advanced.f90:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
program variables_advanced
    implicit none

    ! -- Constants with the parameter attribute --
    real, parameter :: PI = 3.14159265358979
    integer, parameter :: MAX_SIZE = 1000
    character(len=*), parameter :: LANG = "Fortran"

    ! -- Kind specifiers for precision control --
    integer, parameter :: dp = selected_real_kind(15, 307)  ! double precision
    integer, parameter :: sp = selected_real_kind(6, 37)    ! single precision
    integer, parameter :: i64 = selected_int_kind(18)       ! 64-bit integer

    real(kind=dp) :: precise_pi
    real(kind=sp) :: rough_pi
    integer(kind=i64) :: big_number

    ! -- Variables for type conversion demos --
    integer :: int_val
    real :: real_val
    character(len=12) :: str_val

    ! Constants in use
    print *, "PI        =", PI
    print *, "MAX_SIZE  =", MAX_SIZE
    print *, "LANG      = ", LANG

    ! Kind specifiers in action
    precise_pi = 3.141592653589793238_dp
    rough_pi = 3.14159_sp
    big_number = 9000000000000000000_i64

    print *, ""
    print *, "--- Precision comparison ---"
    print *, "rough_pi   =", rough_pi
    print *, "precise_pi =", precise_pi
    print *, "big_number =", big_number

    ! Type conversions using intrinsic functions
    int_val = 7
    real_val = real(int_val)        ! integer to real
    print *, ""
    print *, "--- Type conversions ---"
    print *, "int_val    =", int_val
    print *, "real(7)    =", real_val

    real_val = 9.81
    int_val = int(real_val)         ! real to integer (truncates)
    print *, "int(9.81)  =", int_val

    int_val = nint(9.81)            ! real to nearest integer (rounds)
    print *, "nint(9.81) =", int_val

    ! Number to string
    write(str_val, '(F6.2)') 3.14
    print *, "num to str = ", trim(str_val)

    ! String to number
    str_val = "256"
    read(str_val, *) int_val
    print *, "str to num =", int_val

end program variables_advanced

Key Points

  • parameter makes a variable constant — any attempt to reassign it causes a compile error.
  • character(len=*), parameter lets the compiler determine the string length from the assigned value.
  • selected_real_kind(p, r) requests a real type with at least p significant digits and an exponent range of at least r. This is more portable than hard-coding kind=8.
  • selected_int_kind(r) requests an integer type that can represent values up to 10^r.
  • Type conversion functions: int() truncates, nint() rounds, real() converts to real, dble() converts to double precision.
  • Internal I/O: write(string, fmt) converts numbers to strings and read(string, *) parses strings to numbers — Fortran’s approach to what other languages call toString and parseInt.

Running with Docker

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Pull the official image
docker pull gcc:latest

# Run the basic variables example
docker run --rm -v $(pwd):/app -w /app gcc:latest \
    sh -c "gfortran -o variables variables.f90 && ./variables"

# Run the advanced example
docker run --rm -v $(pwd):/app -w /app gcc:latest \
    sh -c "gfortran -o variables_advanced variables_advanced.f90 && ./variables_advanced"

Expected Output

Output from variables.f90:

 count       =          42
 year        =        1957
 temperature =   98.59999
 pi          =   3.14159012
 name        = Fortran
 greeting    = Hello from Fortran!
 is_valid    = T
 complex z   =             (3.00000000,4.00000000)

Output from variables_advanced.f90:

 PI        =   3.14159274
 MAX_SIZE  =        1000
 LANG      = Fortran

 --- Precision comparison ---
 rough_pi   =   3.14159012
 precise_pi =   3.1415926535897931
 big_number =  9000000000000000000

 --- Type conversions ---
 int_val    =           7
 real(7)    =   7.00000000
 int(9.81)  =           9
 nint(9.81) =          10
 num to str =   3.14
 str to num =         256

Note: Fortran’s default list-directed output (print *, ...) includes a leading space and aligns numbers to field widths. Single-precision real values show approximately 7 significant digits, while double-precision values show approximately 15. The exact formatting may vary slightly between compilers.

Key Concepts

  • All variables must be declared before use when implicit none is specified — this is the modern Fortran best practice that prevents silent bugs from typos.
  • Five intrinsic types cover most needs: integer, real, character, logical, and complex (built-in complex number support is rare among programming languages).
  • The kind system provides portable control over numeric precision using selected_real_kind() and selected_int_kind() rather than assuming specific byte sizes.
  • Constants use parameter — the compiler enforces immutability and can optimize constants more aggressively than variables.
  • Declarations come first — all variable declarations must appear before executable statements, unlike C99+ or Java which allow mid-block declarations.
  • Type conversions are explicit — Fortran provides intrinsic functions like int(), real(), nint(), and dble() for conversions between numeric types.
  • Internal I/O (read/write with character variables) handles string-to-number and number-to-string conversion without external libraries.

Running Today

All examples can be run using Docker:

docker pull gcc:latest
Last updated:

Comments

Loading comments...

Leave a Comment

2000 characters remaining