Coding Fortran: if-else

Decision statements form one of the core elements of any programming language and Fortran is no different. When Fortran first appeared, there was no true if-else statement, and so they were often coded using instruction jumps (goto in disguise and definitely more than meets the eye).

However newer versions of Fortran have moved onto a more contemporary form of the if-else statement, incorporating the keyword then, and like all control structures in Fortran, using the CS terminator end if. Let’s consider an example of finding the roots of a quadratic equation.

program roots

   real :: a, b, c
   real :: discriminant, root1, root2

   print *, 'Input A, B, C'
   read *, a, b, c

   discriminant = b ** 2 - 4.0 * a * c

   if (discriminant < 0.0) then
      print *, 'no real roots'
   else
      root1 = (-b + sqrt(discriminant))/(2.0 * a)
      root2 = (-b - sqrt(discriminant))/(2.0 * a)
      print *, 'roots are ', root1, root2
   end if

end program roots

This program creates a series of real variables, prompts the user for input, calculates the discriminant, and then decides whether the roots can be calculated. Due to the use of a terminator, there is no need to explicitly use a block structure (like C’s { } ) when more than one line of code is needed, either in the then or else part of the if statement. The structure of the if-else statement is similar to that encountered in other languages. The difference is that due to the CS terminators, there is no fear of the dangling else problem occurring. Fortran also protects against expressions like (discriminant = 0), which in C would be valid, but in Fortran assignment in an if-else expression is not allowed. It would produce an error of the form:

if (discriminant = 0.0) then
                1
Error: Syntax error in IF-expression at (1)

Now let’s go back briefly and look at what this code would have looked like in unstructured Fortran:

      program roots

      real a, b, c
      real discriminant, root1, root2

      write (*,*) "Input A, B, C"
      read (*,*) a, b, c

      discriminant = b ** 2 - 4.0 * a * c

      if (discriminant) 10, 20, 20
   10 write (*,*) "No real roots"
      goto 40
   20 root1 = (-b + sqrt(discriminant))/(2.0 * a)
      root2 = (-b - sqrt(discriminant))/(2.0 * a)
      write (*,*) "roots are ", root1, root2
   40 stop

      end program roots

Note how the expressions is now just a single variable, discriminant? These forms of if statements, known as arithmetic if‘s, determined if a mathematical  expression was (i) less than zero, (ii) zero, or (iii) greater than zero, and branched accordingly. In this case if the discriminant is less-than-zero, there are no real roots, so it branches to label 10, which outputs a statement to the user, then branches to label 40, effectively the end of the program (otherwise it would flow through to the code at label 20). The “else” component is the portion of code associated with label 20 (if discriminant is greater than or equal to zero). It works, but isn’t exactly pretty, and as complexity increase leads to spaghetti code.

 

Advertisements

One thought on “Coding Fortran: if-else

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s