June 04, 2025
<aside> 🔖 This short blog post discusses potential “pitfalls” or “gotchas” to watch out for when working with floating-point literal constants in Fortran. These pitfalls, although seemingly innocent, can lead to headaches, confusion, and a cesspool of semantic errors down the line.
Why can’t modern Fortran address these? Well, according to the documentation, doing so would affect backward compatibility with legacy Fortran code, which is still actively used today.
</aside>
When working with literal constants in Fortran, it is a good idea to explicitly specify the “kind” of constant. To reduce word count, I will go ahead and demonstrate this with code.
Without explicitly specifying “kind”
program icomp2
implicit none
integer, parameter :: dp = kind(0d0)
real(kind=dp), parameter :: var = 4.3
print *, precision(var), var
read(*,*) ! freezing my output terminal :-)
end program icomp2
Output: It started off as the IEEE754 single precision floating point (with about 7 significant digits). It is first approximated to a single precision up to the 7th digit, then casted to double precision before being assigned to var.
Correction: explicitly specifying the kind of the constant
real(kind=dp), parameter :: var = 4.3_dp
Output:
Assuming, supposedly, literally out of the blue, let’s try to print-out two-third (2/3) in double precision using our knowledge of Fortran floating points, but, be patient, bare with me…, let’s “forget” to add the floating points after explicitly defining the kind as explained above.
“forgetting (pun-intended)” the floating points:
program icomp2
implicit none
integer, parameter :: dp = kind(0d0)
real(kind=dp), parameter :: two_third = 2_dp / 3_dp
print *, "Two-third = ", two_third
read(*,*) ! freezing my output terminal again ;-)
end program icomp2
Output!: Complete rows of zerosssss!, which is kinda weird, is fortran broken?
Well, it turns out, 1_dp and 3_dp are still treated as integer, despite the _dp suffix and real(kind=dp) definition. The gotcha here is that the standard allows compilers to use identical kind values for REAL and INTEGER types (copied this line from the documentation, I am getting bored…). The solution?, always writing those decimal points lad!