# Finding out default kind values

Hi guys,
I am working through the “Guide to Fortran 2008” book, and I am on page 11.
The 4th exercise is where I am stuck.

4th:
Determine the kind number of one real kind that has precision greater than that of
the default real kind on your computer system.

How do I find the default real kind ? I am using the Intel Fortran compiler: `ifort`

Thanks

Write a short program to do that. Declare a real variable. Apply the various intrinsic functions KIND(), PRECISION, RANGE(), etc., to that variable and print the returned values.

Having done that, you can proceed to tackling the next part of the question, i.e., creating a variable of greater precision.

Note that the standard requires a compiler to provide more than a single REAL kind.

1 Like

@mecej4 answered your question. Here is a program that lists the properties of real number systems for gfortran. The comments mention modifications needed to run it for other compilers.

``````program main ! compiles with gfortran
use iso_fortran_env, only: real_kinds
implicit none
character (len=20) :: fmt = "(7i10,3(1x,es0.4))"
real(kind=4)  :: x4
real(kind=8)  :: x8
real(kind=10) :: x10 ! ifort, flang, and nvfortran reject this
real(kind=16) :: x16 ! flang and nvfortran reject this
print "(a,*(1x,i0))","real_kinds =",real_kinds
print "(7a10,3a10)","kind","storage","digits","precision","range", &
"minexp","maxexp","epsilon","tiny","huge"
print fmt,4,storage_size(x4),digits(x4),precision(x4),range(x4),minexponent(x4), &
maxexponent(x4),epsilon(x4),tiny(x4),huge(x4)
print fmt,8,storage_size(x8),digits(x8),precision(x8),range(x8),minexponent(x8), &
maxexponent(x8),epsilon(x8),tiny(x8),huge(x8)
print fmt,10,storage_size(x10),digits(x10),precision(x10),range(x10),minexponent(x10), &
maxexponent(x10),epsilon(x10),tiny(x10),huge(x10)
print fmt,16,storage_size(x16),digits(x16),precision(x16),range(x16),minexponent(x16), &
maxexponent(x16),epsilon(x16),tiny(x16),huge(x16)
end program main
``````

output:

``````real_kinds = 4 8 10 16
kind   storage    digits precision     range    minexp    maxexp   epsilon      tiny      huge
4        32        24         6        37      -125       128 1.1921E-7 1.1755E-38 3.4028E+38
8        64        53        15       307     -1021      1024 2.2204E-16 2.2251E-308 1.7977E+308
10       128        64        18      4931    -16381     16384 1.0842E-19 3.3621E-4932 1.1897E+4932
16       128       113        33      4931    -16381     16384 1.9259E-34 3.3621E-4932 1.1897E+4932
``````
2 Likes

Thank you both for your help.

One could guess that it should be possible to loop over `real_kinds` parameter array from `iso_fortran_env` module. It is, however, impossible as all the numeric inquiry functions require a declared variable as the argument and the variable can be declared using constant kind value only.

Below, a slightly modified version of @Beliavsky’s code which is a bit less processor-dependent, using values from `real_kinds` array (statically, of course). It assumes the size of `real_kinds` array of 4 (true for gfortran, four different real kinds supported). If a compiler fails because it supports less real kinds, comment out the last declaration (`x4`) and the last `print` statement.

BTW, `ifort` (ver. 2021.4.0) fails to properly render `tiny(x3)` and `huge(x3)` (the largest kind=16) values with `es0.4` format (producing hundreds of `*` characters), so I changed it to `g0.4`

code and output
``````program check_kinds
use iso_fortran_env, only: real_kinds
implicit none
character(len=*), parameter :: fmt = "(7i10,3(1x,g0.4))"
real(kind=real_kinds(1)) :: x1
real(kind=real_kinds(2)) :: x2
real(kind=real_kinds(3)) :: x3
real(kind=real_kinds(4)) :: x4

print "(a,*(1x,i0))","real_kinds =",real_kinds
print "(a,1x,i0)","default real kind =",kind(1.0)
print "(7a10,3a10)","kind","storage","digits","precision","range", &
"minexp","maxexp","epsilon","tiny","huge"
print fmt,kind(x1),storage_size(x1),digits(x1),precision(x1),&
range(x1),minexponent(x1),maxexponent(x1),epsilon(x1),tiny(x1),huge(x1)
print fmt,kind(x2),storage_size(x2),digits(x2),precision(x2),&
range(x2),minexponent(x2),maxexponent(x2),epsilon(x2),tiny(x2),huge(x2)
print fmt,kind(x3),storage_size(x3),digits(x3),precision(x3),&
range(x3),minexponent(x3),maxexponent(x3),epsilon(x3),tiny(x3),huge(x3)
print fmt,kind(x4),storage_size(x4),digits(x4),precision(x4),&
range(x4),minexponent(x4),maxexponent(x4),epsilon(x4),tiny(x4),huge(x4)
end program check_kinds
``````

output (gfortran 11.2):

``````real_kinds = 4 8 10 16
default real kind = 4
kind   storage    digits precision     range    minexp    maxexp   epsilon      tiny      huge
4        32        24         6        37      -125       128 0.1192E-6 0.1175E-37 0.3403E+39
8        64        53        15       307     -1021      1024 0.2220E-15 0.2225E-307 0.1798E+309
10       128        64        18      4931    -16381     16384 0.1084E-18 0.3362E-4931 0.1190E+4933
16       128       113        33      4931    -16381     16384 0.1926E-33 0.3362E-4931 0.1190E+4933
``````

output (ifort 2021.4.0, ‘x4’ commented out):

``````real_kinds = 4 8 16
default real kind = 4
kind   storage    digits precision     range    minexp    maxexp   epsilon      tiny      huge
4        32        24         6        37      -125       128 .1192E-06 .1175E-37 .3403E+39
8        64        53        15       307     -1021      1024 .2220E-15 .2225E-307 .1798E+309
16       128       113        33      4931    -16381     16384 .1926E-33 .3362E-4931 .1190E+4933
``````
1 Like

For the limited purpose of answering the textbook question in the original post, Fortran 95 is sufficient, and one need not assume the kind number of default reals to be known to the programmer in advance.

``````program mykinds
implicit none
real x
!
print *,'Kind of higher precision real = ',selected_real_kind(precision(x)+1)
end program mykinds
``````
1 Like