patternMinor
Calculator in FORTRAN
Viewed 0 times
fortrancalculatorstackoverflow
Problem
This is my first step into Fortran. The program aims to provide a simple way of calculating numbers. Just looking for improvements in general.
program Calc
real :: a, b, additionAnswer, subtractionAnswer, multiplicationAnswer, divisionAnswer
print *, "George Gibson's Calc"
print *, "Type the first number: "
read *, a
print *, "Type the second number: "
read *, b
additionAnswer = a + b
subtractionAnswer = a - b
multiplicationAnswer = a * b
divisionAnswer = a / b
print *, a, " + ", b, " = ", additionAnswer
print *, a, " - ", b, " = ", subtractionAnswer
print *, a, " * ", b, " = ", multiplicationAnswer
print *, a, " / ", b, " = ", divisionAnswer
read *
end program CalcSolution
Functions
A more "Fortrany" way to do this might be to put calculations in their own functions,
where the ellipses (...) mean I'm skipping over the other details. The
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,
The
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
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
-ISO_C_BINDING (need Fortran 2003 or later compiler)
This module is for improved compatibility with C programs/functions. Within it are
-Kind specifier (part of the 1990 standard)
This is the default way to specify the precision without
where
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).
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 programwhere 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 typesKind 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 asprogram 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
useing a module. This is done asprogram 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).
Code Snippets
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 programprint '(f12.6,a3,f12.6,a3,f12.6)', a," + ", b, " = ", AddTwoNums(a,b)program Calc
use iso_fortran_env
real(kind=real64) :: a, b
...program Calc
use iso_c_binding
real(kind=c_double) :: a, b
...program Calc
integer, parameter :: wp = selected_real_kind(15,307)
real(kind=wp) :: a, b
...Context
StackExchange Code Review Q#109379, answer score: 4
Revisions (0)
No revisions yet.