Functions
A more "Fortrany" way to do this might be to put calculations in their own functions,
program Calc
implicit none
...
print *, a, " + ", b, " = ", AddTwoNums(a,b)
print *, a, " - ", b, " = ", SubTwoNums(a,b)
print *, a, " * ", b, " = ", MultTwoNums(a,b)
print *, a, " / ", b, " = ", DivTwoNums(a,b)
contains
pure function AddTwoNums(a,b) result(c)
real, intent(in) :: a,b
real :: c
c = a + b
end function AddTwoNums
...
end program
where the ellipses (...) mean I'm skipping over the other details. The pure
specifier gives details to the compiler that can optimize/vectorize it in some cases (probably not much it can do here, but for some more complex cases it might be useful).
Output
You might also want to specify formats for the output. Since you're using single-precision, you probably want to output the first 6-7 decimal digits,
print '(f12.6,a3,f12.6,a3,f12.6)', a," + ", b, " = ", AddTwoNums(a,b)
The f12.6
means it's a floating-point type number with 12 total digits and 6 after the decimal, a3
means it is a character string of length 3 (you can make this one simply a
and let the compiler figure it out).
Precision
Single precision is nice, but you can do better; and there's a few ways how:
-ISO_FORTRAN_ENV (needs Fortran 2008 or later compiler)
Within this big module is the real32
, real64
, and real132
types
Kind type parameters to specify a REAL type with a storage size of 32, 64, and 128 bits. It is negative if a target platform does not support the particular kind. (Fortran 2008 or later.)
and would be used as
program Calc
use iso_fortran_env
real(kind=real64) :: a, b
...
-ISO_C_BINDING (need Fortran 2003 or later compiler)
This module is for improved compatibility with C programs/functions. Within it are C_double
and C_long_double
types that will match the equivalent C types. This would be used as
program Calc
use iso_c_binding
real(kind=c_double) :: a, b
...
-Kind specifier (part of the 1990 standard)
This is the default way to specify the precision without use
ing a module. This is done as
program Calc
integer, parameter :: wp = selected_real_kind(15,307)
real(kind=wp) :: a, b
...
where wp
is typically short for "working precision" (some people choose to append an underscore in case they want to use wp
as a variable). The first number in selected_real_kind
is the decimal precision and the second number is the exponent range (-307 to +307). You are also not restricted to using integers associated with any particular precision (single or double) here, you can choose to use selected_real_kind(10,40)
, for instance. Fortran 2003 standards specify that absent values for the precision & radix are assumed to be zero.
Comments
This is general and not specific to Fortran, but I'm a big fan & proponent of comments. Even when it's absolutely trivial & blatantly obvious what is being done on the line below, it benefits you (as practice for the more complex computations) and potential future readers (so that they know what is being done & why).