Fortran DISCUSSION

Fortran integer*4, integer(4) and integer(kind=4): which declaration style is portable?

Started by silent96 Fortran kind parameterselected_real_kindiso_fortran_envdouble precision literalsreal(8)
5 replies 248 views 6 participants
Latest activity · 30 Sep 2026

Fortran integer*4, integer(4) and integer(kind=4): which declaration style is portable?

silent96 Fortran Forum
#1

The code I inherited mixes real*8, real(8), real(kind=8) and double precision, and newer files use real(dp) with dp defined in a module. They all seem to give 64-bit reals with gfortran.

Are these really equivalent, which form should I standardise on, and why does real(dp) :: x = 0.1 print as 0.10000000149011612 instead of 0.1 when the variable is supposed to be double precision?

Community replies 5

Re: Fortran integer*4, integer(4) and integer(kind=4): which declaration style is portable?

#2

real*8 and integer*4 are an extension from before Fortran 90. Nearly every compiler accepts them, but they have never been part of the standard. real(8) and real(kind=8) are identical to each other and are standard syntax, but the meaning of the number 8 is not fixed: kind values are chosen by the compiler. Most compilers use the size in bytes, so 8 is a 64-bit real, but a compiler may number its kinds 1, 2, 3, and the NAG compiler does so by default.

double precision is standard and portable, just not parameterisable.

Re: Fortran integer*4, integer(4) and integer(kind=4): which declaration style is portable?

#3

The portable approach is to ask for what you need and store the answer in a named constant. Either request a precision, integer, parameter :: dp = selected_real_kind(15, 307) (at least 15 decimal digits and a decimal exponent range of 307, which is IEEE double), or use the constants from the intrinsic module: use, intrinsic :: iso_fortran_env, only: real64, int32. For integers, selected_int_kind(9) asks for a range of at least ±10^9, which gives a 32-bit integer.

Put the definitions in one module and use it everywhere, so that changing precision later is a one-line edit.

Re: Fortran integer*4, integer(4) and integer(kind=4): which declaration style is portable?

#4

The 0.1 problem is about the literal, not the variable. 0.1 without a suffix is a default real constant, single precision on most compilers. It is rounded to about 7 significant digits first, giving 0.100000001490116..., and that value is then converted exactly to double. The extra digits of the variable cannot restore what the constant never had.

Write 0.1_dp. The same applies inside expressions such as x * 0.1 or 2.0/3.0: every real constant in double precision code needs the kind suffix. 0.1d0 also works, but ties the constant to double precision rather than to dp.

Re: Fortran integer*4, integer(4) and integer(kind=4): which declaration style is portable?

#5

Related habits worth adopting at the same time. Define mathematical constants with the working kind, for example real(dp), parameter :: pi = 4.0_dp * atan(1.0_dp), so the value is as accurate as the type allows instead of a hand-typed decimal. Convert with the kind argument, real(n, dp), because plain real(n) returns default real.

To find constants that are missing the suffix in existing code, gfortran's -Wconversion-extra option reports implicit conversions between kinds.

Re: Fortran integer*4, integer(4) and integer(kind=4): which declaration style is portable?

#6

If the requirement is a storage size rather than a precision, for example reading a binary file or matching a C struct, state that directly. real64 and int32 from iso_fortran_env are defined by size in bits, and for C interfaces the constants c_double, c_int and the others from iso_c_binding match the companion C compiler by definition.

You can check what you got with storage_size(x), which returns the size in bits, and with precision(x) and range(x); for an IEEE double these give 64, 15 and 307.

TEP COMMUNITY