Fortran 90 Tutorial
Fortran 90 Tutorial Dr. C.-K. Shene Associate Professor Department of Computer Science Michigan Technological University © 1997 C.-K. Shene
since July 1, 1998. You are visitor Last update: August 20, 1998.
Select the topics you wish to review: Introduction and Basic Fortran Selective Execution (IF-THEN-ELSE and SELECT CASE) Repetitive Execution (DO Loops) Functions and Modules Subroutines One-Dimensional Arrays Multi-Dimensional Arrays Formated Input and Output Please send comments and suggestions to
[email protected]
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/fortran.html8/5/2006 8:01:06 PM
Introduction and Basic Fortran
Introduction and Basic Fortran Select the topics you wish to review: Introduction Program Structure Comments Continuation Lines Basic Fortran Alphabets Constants Identifiers Variables and Their Types Variable Declarations Assigning a Constant a Name - PARAMETER attribute Initializing Variables Arithmetic Operators Simple Mode Arithmetic Expressions Mixed Mode Arithmetic Expressions The Assignment Statement Intrinsic Functions List-Directed Input: The READ Statement List-Directed Output: The WRITE Statement Programming Examples: Three Programming Traps Computing Means Quadratic Equation Solver The Length of a Parabola Segment Projectile motion (intrinsic functions) Character Operator and Substrings (Optional) Download my course overheads
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/intro.html8/5/2006 8:01:34 PM
Program structure
Program Structure Your program should have the following form: PROGRAM program-name IMPLICIT NONE [specification part] [execution part] [subprogram part] END PROGRAM program-name
Here are some addition notes: ● ● ●
●
Contents in [ ] are optional. Keyword IMPLICIT NONE must present. A program starts with the keyword PROGRAM, ❍ followed by a program name, ❍ followed by the IMPLICIT NONE statement, ❍ followed my some specification statements, ❍ followed by the execution part, ❍ followed by a set of internal subprograms, ❍ followed by the keywords END PROGRAM and the program name. For improving readability, your program should add comment lines.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap01/struct.html8/5/2006 8:01:48 PM
Fortran identifiers
Fortran Identifiers A Fortran identifier must satisfy the following rules: ● ● ● ● ●
●
●
●
It has no more than 31 characters The first character must be a letter, The remaining characters, if any, may be letters, digits, or underscores, Fortran identifiers are case insensitive. That is, Smith, smith, sMiTh, SMiTH, smitH are all identical identifiers. Correct Examples: ❍ MTU, MI, John, Count ❍ I, X ❍ I1025, a1b2C3, X9900g ❍ R2_D2, R2D2_, A__ Incorrect Examples: ❍ M.T.U.: only letters, digits, and underscores can be used ❍ R2-D2: same as above ❍ 6feet: the first character must be a letter ❍ _System: same as above Use meaningful names ❍ Good names: Total, Rate, length ❍ Not so good names: ThisIsALongFORTRANname, X321, A_B_012cm, OPQ Fortran has many keywords such as INTEGER, REAL, PARAMETER, PROGRAM, END, IF, THEN, ELSE, DO, just name a few; however, Fortran does not have any reserved words. More precisely, a programmer can use these keywords as identifiers. Therefore, END, PROGRAM, DO are perfectly legal Fortran identifiers. However, this is definitely not a good practice.
Except for strings, Fortran 90 is not case sensitive. Therefore, identifier Name is identical to name, nAmE, NAme, NamE and namE. Similarly, PROGRAM is identical to program, PROgram, and progRAM. In this course, all keywords such as PROGRAM, READ, WRITE and END are in upper case and other identifiers use mixed cases.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/id.html8/5/2006 8:01:56 PM
Fortran comments
Fortran Comments Comments should be used liberally to improve readability. The following are the rules for making comments: ●
All characters following an exclamation mark, !, except in a character string, are commentary, and are ignored by the compiler. PROGRAM TestComment1 .......... READ(*,*) Year ! read in the value of Year .......... Year = Year + 1 ! add 1 to Year .......... END PROGRAM TestComment1
●
An entire line may be a comment ! This is a comment line ! PROGRAM TestComment2 ......... ! This is a comment line in the middle of a program ......... END PROGRAM TestComment2
●
A blank line is also interpreted as a comment line. PROGRAM TestComment3 .......... READ(*,*) Count ! The above blank line is a comment line WRITE(*,*) Count + 2 END PROGRAM TestComment3
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap01/comment.html8/5/2006 8:02:03 PM
Fortran alphabets
Fortran Alphabets Fortran only uses the following characters: ●
Letters: A N a n
●
B O b o
C P c p
D Q d q
E R e r
F S f s
G T g t
H U h u
I V i v
J W j w
K X k x
L Y l y
M Z m z
Digits: 0 1 2 3 4 5 6 7 8 9
●
Special Characters: space ' " ( ) * + - / : = _ ! & $ ; < > % ? , .
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/alphabet.html8/5/2006 8:02:12 PM
Fortran continuation lines
Fortran Continuation Lines In Fortran, a statement must start on a new line. If a statement is too long to fit on a line, it can be continued with the following methods: ● ●
If a line is ended with an ampersand, &, it will be continued on the next line. Continuation is normally to the first character of the next non-comment line. A = 174.5 * Year + Count / 100
&
The above is equivalent to the following A = 174.5 * Year
+ Count / 100
Note that &is notpart of the statement. A = 174.5 * Year & ! this is a comment line + Count / 100 The above is equivalent to the following, since the commentis ignored by the compiler: A = 174.5 * Year ●
+ Count / 100
If the first non-blank character of the continuation line is &, continuation is to the first character after the &: A = 174.5 + ThisIsALong& &VariableName * 123.45 is equivalent to A = 174.5 + ThisIsALongVariableName * 123.45 In this case, there should be no spaces between the last character and the &on the first line. For example, A = 174.5 + ThisIsALong & &VariableName * 123.45 is equivalent to A = 174.5 + ThisIsALong
VariableName * 123.45
Note that there are spaces between ThisIsALongand VariableName. In this way, a token (name and number) can be split over two lines. However, this is not recommended
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap01/continue.html8/5/2006 8:02:34 PM
Fortran Constants
Fortran Constants Constants or more formally literal constants are the tokens used to denote the value of a particular type. Fortran has five types of constants: integer, real, complex, logical, and character string. ●
●
● ● ●
Integer Constants: a string of digits with an optional sign: ❍ Correct Examples: 0, -345, 768, +12345 ❍ Incorrect Examples: ■ 1,234 : comma is not allowed ■ 12.0: no decimal point ■ --4 and ++3: too many optional signs ■ 5- and 7+: the optional sign must precede the string of digits Real Constants: There are two representations, decimal representation and exponential representation. ❍ Decimal Representation: A decimal point must be presented, but no commas are allowed. A real constant can have an optional sign. ■ Correct Examples: 23.45, .123, 123., -0.12, -.12 ■ Incorrect Examples: ■ 12,345.95: no comma is allowed ■ 75: real constant must have a decimal point ■ 123.5-: the optional sign must precede the number ■ $12.34: cannot use dollar sign $ ❍ Exponential Representation: It consists of an integer or a real number in decimal representation (the mantissa or fractional part), followed by the letter E or e, followed by an integer (the exponent). ■ Correct Examples ■ 12.3456E2 or 12.3456e2: this is equal to 1234.56 ■ -3.14E1 or -3.14e1: this is equal to -31.4 ■ -1.2E-3 or -1.2e-3: this is equal to -0.0012 ■ 12E3 or 12e3: this is equal to 12000.0 ■ 0E0 or 0e0: this is equal to 0.0 ■ Incorrect Examples ■ 12.34E1.2: the exponential part must be an integer constant ■ 12.34-5: there is no exponential sign E or e Complex: Will not be covered in this course Logical: See Chapter 3 Character String: Character constants must be enclosed between double quotes or apostrophes (single quotes). The content of a string consists of all characters, spaces included, between the single or quote quotes, while the length of the string is the number of characters of its content. The content of a string can be zero and in this case it is an empty string ❍ Correct Examples: ■ 'John' and "John": content = John and length = 4 ■ ' ' and " ": content = a single space and length = 1 ■ 'John Dow #2' and "John Dow #2": content = John Dow #2 and length = 11 ■ '' and "": content = nothing and length = 0 (empty string) ❍ Incorrect Examples: ■ 'you and me: the closing apostrophe is missing ■ Hello, world': the opening apostrophe is missing ■ 'Hi" and "Hi': the opening and closing quotes do not match. If single quote is used in a string, then double quotes should be used to enclose the string:
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/constant.html (1 of 2)8/5/2006 8:02:42 PM
Fortran Constants
"Lori's apple" This string has content Lori's apple and length 12. Alternatively, you can write the single quote twice as follows: 'Lori''s apple' The compiler will treat a pair of single quotes in the content of a string as one. Thus, the content of the above string is still Lori's apple. ❍ Correct Examples: ■ 'What''s this?': content = What's this? and length = 11 ■ '''''': content = '' and length = 2 ❍ Incorrect Examples: ■ 'Tech's seminar': the single quote between h and s should be written twice.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/constant.html (2 of 2)8/5/2006 8:02:42 PM
Fortran Variables and Their Types
Fortran Variables and Their Types A Fortran variable can be considered as a box that is capable of holding a single value of certain type. Thus, a variable has a name, the variable name and a type. The way of choosing a name for a variable must fulfill the rules of composing a Fortran identifier. The type of a variable can be one of the following: ● ● ● ● ●
INTEGER: the variable is capable of holding an integer REAL: the variable is capable of holding a real number COMPLEX: the variable is capable of holding a complex number LOGICAL: the variable is capable of holding a logical value (i.e., true or false) CHARACTER: the variable is capable of holding a character string of certain length
Click here to learn the forms of these values. Click here to learn more about declaring variables.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/var-type.html8/5/2006 8:02:49 PM
Fortran Variable Declarations
Fortran Variable Declarations Declaring the type of a Fortran variable is done with type statements. It has the following form: type-specifier :: list where the type-specifier is one of the following and list is a list of variable names separated with commas: ● ● ● ● ●
INTEGER : the variables in list can hold integers REAL: the variables in list can hold real numbers COMPLEX: the variables in list can hold complex numbers LOGICAL: the variables in list can hold logical values (i.e., true or false) CHARACTER: the variables in list can hold character strings
Types INTEGER and REAL are easy. The following are examples: ●
Variables ZIP, Mean and Total are of type INTEGER: INTEGER :: ZIP, Mean, Total
●
Variables Average, error, sum and ZAP are of type REAL: REAL
::
Average, error, sum, ZAP
Type CHARACTER is more involved. Since a string has a length attribute, a length value must be attached to character variable declarations. There are two ways to do this: ●
Use CHARACTER(LEN=i) to declare character variables of length i. For examples, ❍ Name and Street are character variables that can hold a string of no more than 15 characters: CHARACTER(LEN=15) :: Name, Street ❍
FirstName, LastName and OtherName are character variables that can hold a string of no more than 20 characters: CHARACTER(LEN=20) :: FirstName, LastName, OtehrName
●
Use CHARACTER(i) to declare character variables of length i. That is, there is no LEN= in the parenthesis. For examples, ❍ Name and Street are character variables that can hold a string of no more than 15 characters: CHARACTER(15) :: Name, Street ❍
FirstName, LastName and OtherName are character variables that can hold a string of no more than 20 characters:
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/declare.html (1 of 2)8/5/2006 8:02:50 PM
Fortran Variable Declarations
CHARACTER(20) :: FirstName, LastName, OtehrName ●
If a variable can only hold a single character, the length part can be removed. The following three declarations are all equivalent: CHARACTER(LEN=1) CHARACTER(1) CHARACTER
:: letter, digit :: letter, digit :: letter, digit
Here, variables letterand digitcan only hold no more than one character. ●
If you want to declare character variables of different length with a single statement, you can attach a length specification, *i, to the right of a variable. In this case, the corresponding variable will have the indicated length and all other variables are not affected. CHARACTER(LEN=10) :: City, Nation*20, BOX, bug*1 Here, variables Cityand BOXcan hold a string of no more than 10 characters, Nationcan hold a string of no more than 20 characters, and bugcan hold only one character.
●
There is one more way of specifying the length of a character variable. If the length value is replaced with a asterisk *, it means the lengths of the declared variables are determined elsewhere. In general, this type of declarations is used in subprogram arguments or in PARAMETER and is refereed to as assumed length specifier. CHARACTER(LEN=*) :: Title, Position Here, the actual lengths of variables Titleand Positionare unknown and will be determined elsewhere.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/declare.html (2 of 2)8/5/2006 8:02:50 PM
The PARAMETER Attribute
The PARAMETER Attribute In many places, one just wants to assign a name to a particular value. For example, keep typing 3.1415926 is tedious. In this case, one could assign a name, say PI, to 3.1415926 so that one could use PI rather than 3.1415926. To assign a name to a value, one should do the following: ●
●
●
●
●
Add PARAMETER in front of the double colon (::) and use a comma to separate the type name (i.e., REAL) and the word PARAMETER Following each name, one should add an equal sign (=) followed by an expression. The value of this expression is then assigned the indicated name. After assigning a name to a value, one can use the name, rather than its value throughout the program. The compiler would convert that name to its corresponding value. It is important to note that the name assigned to a value is simply an alias of the value. Therefore, that name is not a variable. After assigning a name to a value, that name can be used in a program, even in subsequent type statements.
Examples: ●
In the example blow, Limit is a name for the integer value 30, while Max_Count is a name for the integer value 100: INTEGER, PARAMETER :: Limit = 30, Max_Count = 100
●
In the example below, E is a name for the real value 2.71828, while PI is a name for the real value 3.141592: REAL, PARAMETER :: E = 2.71828, PI = 3.141592
●
In the example below, Total and Count are names for 10 and 5, respectively. The name, Sum, is defined to be the product of the values of Total and Count and hence Sum is the name for the value 50(=10*5). INTEGER, PARAMETER :: Total = 10, Count = 5, Sum = Total*Count
●
In the example below, Name is a name for the string 'John' and State is a name for the string "Utah" CHARACTER(LEN=4), PARAMETER :: Name = 'John', State = "Utah" It is importantto know when assigning a name to a string: ❍ If the string is longer, truncation to the right will happen. In the following case, since the length of the string "Smith" is 5 while the length of Name is 4, the string is truncated to the right and the content of Name is "Smit" CHARACTER(LEN=4), PARAMETER :: Name = 'Smith' ❍
If the string is shorter, spaces will be added to the right. Since the string "LA" is of length 2 while the name
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/param.html (1 of 2)8/5/2006 8:02:52 PM
The PARAMETER Attribute
City is of length 4, two spaces will be padded to the right and the content of City becomes "LA " CHARACTER(LEN=4), PARAMETER :: City = "LA" ●
This is where the assumed length specifier comes in. That is, Fortran allows the length of character name to be determined by the length of s string. In the example below, names Name and City are declared to have assumed length. Since the lengths of 'John' and "LA" are 4 and 2, the length of the names Name and City are 4 and 2, respectively. CHARACTER(LEN=*), PARAMETER :: Name = 'John', City = "LA"
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/param.html (2 of 2)8/5/2006 8:02:52 PM
Variables Initialization
Variables Initialization A variable can be considered as a box that can hold a single value. However, initially the content of a variable (or a box) is empty. Therefore, before one can use a variable, it must receive a value. Do not assume the compiler or computer will put some value, say 0, into a variable. There are at least three ways to put a value into a variable: ● ● ●
initializing it when the program is run using an assignment statement reading a value from keyboard or other device with a READ statement.
The way of initializing a variable is very similar to the use of PARAMETER attribute. More precisely, do the following to initial a variable with the value of an expression: ● ●
add an equal sign (=) to the right of a variable name to the right of the equal sign, write an expression. It is important to note that all names in the expression must constants or names of constants.
Initializing a variable is only done exactly once when the computer loads your program into memory for execution. That is, all initializations are done before the program starts its execution. Using un-initialized variables may cause unexpected result.
Examples: ●
The following example initializes variables Offset to 0.1, Length to 10.0, and tolerance to 1.E-7. REAL :: Offset = 0.1, Length = 10.0, tolerance = 1.E-7
●
The following example initializes variables State1 to "MI", State2 to "MN", and State3 to "MD". CHARACTER(LEN=2) :: State1 = "MI", State2 = "MN", State3 = "MD"
●
The following example first defines three named integer constants with PARAMETER and uses these values to initialize two integer variables. Thus, variables Pay and Received are initialized to have values 4350 (=10*435) and 8 (3+5), respectively. INTEGER, PARAMETER :: Quantity = 10, Amount = 435, Period = 3 INTEGER :: Pay = Quantity*Amount, Received = Period+5
●
The following example contains a mistake. While the compiler is processing the initialization value for variable Received, the value of Period is unknown, although it will be defined on the next line. INTEGER, PARAMETER :: Quantity = 10, Amount = 435 INTEGER :: Pay = Quantity*Amount, Received = Period+5 INTEGER, PARAMETER :: Period = 3
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/var-init.html8/5/2006 8:02:53 PM
Arithmetic Operators
Arithmetic Operators Fortran has four types of operators: arithmetic, relational, logical, and character. The following is a table of these operators, including their priority and associativity. Type Arithmetic
Operator
Associativity
**
right to left
*
/
left to right
+
-
left to right
Relational < >= ==
Logical
/ =
none
.NOT.
right to left
.AND.
left to right
.OR.
left to right
.EQV.
.NEQV.
left to right
Some Useful Notes: ●
●
●
●
●
In the table, the operator on the top-most row (**) has the highest priority (i.e., it will be evaluated first) while the operators on the bottom-most row (i.e., .EQV. and .NEQV.) have the lowest priority. The operators on the same row have the same priority. In this case, the order of evaluation is based on their associativity law. In addition to addition +, subtraction -, multiplication * and division /, Fortran has an exponential operator **. Thus, raising X to the Y-th power is written as X**Y. For example, the square of 5 is 5**2, and the square root of 5 is 5**0.5. The exponential operator has the highest priority. Operators + and - can also be used as unary operators, meaning that they only need one operand. For example, -A and +X. The former means change the sign of A, while the latter is equivalent to X. Unary operators + and - have the same priority as their binary counterparts (i.e., addition + and subtraction -). As a result, since ** is higher than the negative sign -, -3**2 is equivalent to -(3**2), which is -9. For arithmetic operators, the exponential operator ** is evaluated from right to left. Thus, A**B**C is equal to A** (B**C) rather than (A**B)**C
Click here for single mode arithmetic expressions Click here for mixed mode arithmetic expressions
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/operator.html8/5/2006 8:02:55 PM
Single Mode Arithmetic Expressions
Single Mode Arithmetic Expressions An arithmetic expression is an expression using additions +, subtractions -, multiplications *, divisions /, and exponentials **. A single mode arithmetic expression is an expression all of whose operands are of the same type (i.e. INTEGER, REAL or COMPLEX). However, only INTEGER and REAL will be covered in this note. Therefore, those values or variables in a single mode arithmetic expression are all integers or real numbers. In single mode arithmetic expressions, the result of an operation is identical to that of the operands. The following is a table showing this fact. The empty entries will be discussed in mixed mode arithmetic expressions. Operator
INTEGER
REAL
INTEGER INTEGER mixed mode REAL
mixed mode
REAL
Simple Examples: ● ● ● ● ● ● ● ●
●
1 + 3 is 4 1.23 - 0.45 is 0.78 3 * 8 is 24 6.5/1.25 is 5.2 8.4/4.2 is 2.0 rather than 2, since the result must be of REAL type. -5**2 is -25 12/4 is 3 13/4 is 3 rather than 3.25. Since 13/4 is a single mode arithmetic expression and since all of its operands are of INTEGER type, the result must also be of INTEGER type. The computer will truncate the mathematical result (3.25) making it an integer. Therefore, the result is 3. 3/5 is 0 rather than 0.6.
Rules for Evaluating Expressions The following are rules of evaluating a more complicated single mode arithmetic expression: ● ●
Expressions are always evaluated from left to right If an operator is encountered in the process of evaluation, its priority is compared with that of the next one: ❍ if the next one is lower, evaluate the current operator with its operands 3 * 5 - 4 In the above expression, in the left to right scan, operator *is encountered first. Since the the operator -is lower, 3 * 5is evaluated first transforming the given expression to 15 - 4. Hence, the result is 11.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/exp-1.html (1 of 3)8/5/2006 8:02:56 PM
Single Mode Arithmetic Expressions ❍
❍
if the next one is equal to the current, the associativity rules are used to determine which one should be evaluated. For example, if both the current and the next operators are *, then 3 * 8 * 6 will be evaluated as (3 * 8) * 6. On the other hand, if the operator is **, A ** B ** C will be evaluated as A ** (B ** C). if the next one is higher than the current, the scan should continue with the next operator. For example, consider the following expression: 4 + 5 * 7 ** 3 if the current operator is +, since the next operator *has higher priority, the scan continues to *. Once the scan arrives at *, since the next operator **is higher, 7 ** 3is evaluated first, transforming the given expression to 4 + 5 * 343 Then, the new expression is scan again. The next operator to be evaluated is *, followed by +. Thus, the original expression is evaluated as 4 + (5 * (7 ** 3)).
More Complicated Examples: In the following examples, brackets are used to indicated the order of evaluation. ●
The result is 4 rather than 4.444444 since the operands are all integers. 2 * 4 * 5 / 3 ** 2 --> [2 * 4] * 5 / 3 ** 2 --> 8 * 5 / 3 ** 2 --> [8 * 5] / 3 ** 2 --> 40 / 3 ** 2 --> 40 / [3 ** 2] --> 40 / 9 --> 4
●
As in mathematics, subexpressions in parenthesis must be evaluated first. 100 + (1 --> --> --> --> --> --> -->
●
+ 250 100 + 100 + 100 + 100 + 100 + 100 + 127
/ 100) ** 3 (1 + [250 / 100]) ** 3 (1 + 2) ** 3 ([1 + 2]) ** 3 3 ** 3 [3 ** 3] 27
In the following example, x**0.25 is equivalent to computing the fourth root of x. In general, taking the k-th root of x is equivalent to x**(1.0/k) in Fortran, where k is a real number. 1.0 + 2.0 * 3.0 / ( 6.0*6.0 + 5.0*44.0) ** 0.25 --> 1.0 + [2.0 * 3.0] / (6.0*6.0 + 5.0*44.0) ** 0.25
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/exp-1.html (2 of 3)8/5/2006 8:02:56 PM
Single Mode Arithmetic Expressions
--> --> --> --> --> --> --> --> --> --> --> -->
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 2.5
+ + + + + + + + + + +
6.0 / (6.0*6.0 + 5.0*55.0) ** 0.25 6.0 / ([6.0*6.0] + 5.0*44.0) ** 0.25 6.0 / (36.0 + 5.0*44.0) ** 0.25 6.0 / (36.0 + [5.0*44.0]) ** 0.25 6.0 / (36.0 + 220.0) ** 0.25 6.0 / ([36.0 + 220.0]) ** 0.25 6.0 / 256.0 ** 0.25 6.0 / [256.0 ** 0.25] 6.0 / 4.0 [6.0 / 4.0] 1.5
Click here to continue with mixed mode arithmetic expressions.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/exp-1.html (3 of 3)8/5/2006 8:02:56 PM
Mixed Mode Arithmetic Expressions
Mixed Mode Arithmetic Expressions If operands in an expression contains both INTEGER and REAL constants or variables, this is a mixed mode arithmetic expression. In mixed mode arithmetic expressions, INTEGER operands are always converted to REAL before carrying out any computations. As a result, the result of a mixed mode expression is of REAL type. The following is a table showing this fact. Operator
INTEGER REAL
INTEGER INTEGER REAL REAL
REAL
REAL
The rules for evaluating mixed mode arithmetic expressions are simple: ● ●
●
Use the rules for evaluating single mode arithmetic expressions for scanning. After locating an operator for evaluation, do the following: ❍ if the operands of this operator are of the same type, compute the result of this operator. ❍ otherwise, one of the operand is an integer while the other is a real number. In this case, convert the integer to a real (i.e., adding .0 at the end of the integer operand) and compute the result. Note that since both operands are real numbers, the result is a real number. There is an exception, though. In a**n, where a is a real and n is a positive integer, the result is computed by multiplying n copies of a. For example, 3.5**3 is computed as 3.5*3.5*3.5
Simple Examples: ● ● ● ● ●
1 + 2.5 is 2.5 1/2.0 is 0.5 2.0/8 is 0.25 -3**2.0 is -9.0 4.0**(1/2) is first converted to 4.0**0 since 1/2 is a single mode expression whose result is 0. Then, 4.0**0 is 1.0
An Important Note: In expression a**b where a is REAL, the result is undefined if the value of a is negative. For example, 4.0**2 is defined with -16.0 as its result, while (-4.0)**2 is undefined.
More Complicated Examples:
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/exp-2.html (1 of 2)8/5/2006 8:02:58 PM
Mixed Mode Arithmetic Expressions
In the following, brackets will be used to indicated the order of evaluation and braces will be used to indicated an integer-toreal conversion. ●
Note that 6.0 ** 2 is not converted to 6.0 ** 2.0. Instead, it is computed as 6.0 * 6.0. 5 * (11.0 - 5) ** 2 / 4 + 9 --> 5 * (11.0 - {5}) ** 2 / 4 + 9 --> 5 * (11.0 - 5.0) ** 2 / 4 + 9 --> 5 * ([11.0 - 5.0]) ** 2 / 4 + 9 --> 5 * 6.0 ** 2 / 4 + 9 --> 5 * [6.0 ** 2] / 4 + 9 --> 5 * 36.0 / 4 + 9 --> {5} * 36.0 / 4 + 9 --> 5.0 * 36.0 / 4 + 9 --> [5.0 * 36.0] / 4 + 9 --> 180.0 / 4 + 9 --> 180.0 / {4} + 9 --> 180.0 / 4.0 + 9 --> [180.0 / 4.0] + 9 --> 45.0 + 9 --> 45.0 + {9} --> 45.0 + 9.0 --> 54.0
●
In the following, 25.0 ** 1 is not converted, and 1 / 3 is zero. 25.0 ** 1 / 2 * 3.5 ** (1 / 3) --> [25.0 ** 1] / 2 * 3.5 ** (1 / 3) --> 25.0 / 2 * 3.5 ** (1 / 3) --> 25.0 / {2} * 3.5 ** (1 / 3) --> 25.0 / 2.0 * 3.5 ** (1 / 3) --> 12.5 * 3.5 ** (1 / 3) --> 12.5 * 3.5 ** ([1 / 3]) --> 12.5 * 3.5 ** 0 --> 12.5 * [3.5 ** 0] --> 12.5 * 1.0 --> 12.5
Click here to continue with single mode arithmetic expressions.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/exp-2.html (2 of 2)8/5/2006 8:02:58 PM
The Assignment Statement
The Assignment Statement The assignment statement has the following form: variable = expression Its purpose is saving the result of the expression to the right of the assignment operator to the variable on the left. Here are some rules: ● ● ●
● ●
The expression is evaluated first with the rules discussed in the single mode or the mixed mode expressions pages. If the type of the expression is identical to that of the variable, the result is saved in the variable. Otherwise, the result is converted to the type of the variable and saved there. ❍ If the type of the variable is INTEGER while the type of the result is REAL, the fractional part, including the decimal point, is removed making it an integer result. ❍ If the type of the variable is REAL while the type of the result is INTEGER, then a decimal point is appended to the integer making it a real number. Once the variable receives a new value, the original one disappears and is no more available. CHARACTER assignment follows the rules stated in the discussion of the PARAMETER attribute.
Examples: ●
The program segment below declares three INTEGER variables. The first assignment statement saves an integer value to variable Unit. The second saves a real number 100.99 into variable Amount. However, since Amount is an INTEGER variable, the real value 100.99 is converted to an integer, 100, and saved into Amount. Thus, after the second assignment completes, variable Amount holds 100. The third assignment computes the single mode expression, yielding a result 500 = 5*100. Thus, variable Total receives 500. INTEGER :: Total, Amount, Unit Unit = 5 Amount = 100.99 Total = Unit * Amount
●
In the following, PI is a PARAMETER and is an alias of 3.1415926. The first assignment statement puts integer value 5 into integer variable Radius. The expression in the second assignment is first evaluated, yielding a result 78.539815, which is then saved into REAL variable Area. REAL, PARAMETER :: PI = 3.1415926 REAL :: Area INTEGER :: Radius Radius = 5 Area = (Radius ** 2) * PI
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/assign.html (1 of 3)8/5/2006 8:03:06 PM
The Assignment Statement ●
In the following, Counter is an INTEGER variable initialized to zero. The meaning of the first assignment is computing the sum of the value in Counter and 1, and saves it back to Counter. Since Counter's current value is zero, Counter + 1 is 1+0 = 1 and hence 1 is saved into Counter. Therefore, the new value of Counter becomes 1 and its original value 0 disappears. The second assignment statement computes the sum of Counter's current value and 3, and saves the result back to Counter. Thus, the new value of Counter is 1+3=4. INTEGER
::
Counter = 0
Counter = Counter + 1 Counter = Counter + 3 ●
The following swaps the values in A and B, with the help of C. That is, after completing the following three assignment statements, A and B have 5 and 3, respectively. Initially, A and B are initialized to 3 and 5, respectively, while C is uninitialized. The first assignment statement puts A's value into C, making A=3, B=5 and C=3. The second assignment statements puts B's value into A. This destroys A's original value 3. After this, A = 5, B = 5 and C = 3. The third assignment statement puts C's value into B. This makes A=5, B=3 and C=3. Therefore, the values in A and B are exchanged. INTEGER
:: A = 3, B = 5, C
C = A A = B B = C The following is another possible solution; but, it uses one more variable. INTEGER :: A = 3, B = 5, C, D C D A B
= = = =
A B D C
An Important Note: A name declared with the PARAMETER attribute is an alias of a value and is not a variable. Therefore, it cannot be used on the left-hand side of =, although it can be used on the right-hand side. The following is wrong!
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/assign.html (2 of 3)8/5/2006 8:03:06 PM
The Assignment Statement
INTEGER, PARAMETER INTEGER
:: InchToCM = 2.54, factor = 123.45 :: X = 15
InchToCM = factor * X
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/assign.html (3 of 3)8/5/2006 8:03:06 PM
Fortran Intrinsic Functions
Fortran Intrinsic Functions Fortran provides many commonly used functions, called intrinsic functions. To use a Fortran function, one needs to understand the following items: ● ● ● ● ●
the name and meaning of the function such as ABS() and SQRT() the number of arguments the range of the argument the types of the arguments the type of the return value or the function value
For example, function SQRT() accepts a REAL argument whose value must be non-negative and computes and returns the square root of the argument. Therefore, SQRT(25.0) returns the square root of 25.0 and SQRT(-1.0) would cause an error since the argument is negative. ●
Mathematical functions:
Function ABS(x)
Meaning absolute value of x
Arg. Type
Return Type
INTEGER INTEGER REAL
REAL
SQRT(x) square root of x
REAL
REAL
SIN(x)
sine of x radian
REAL
REAL
COS(x)
cosine of x radian
REAL
REAL
TAN(x)
tangent of x radian
REAL
REAL
ASIN(x)
arc sine of x
REAL
REAL
ACOS (x)
arc cosine of x
REAL
REAL
ATAN (x)
arc tangent of x
REAL
REAL
EXP(x)
exp(x)
REAL
REAL
LOG(x)
natural logarithm of x
REAL
REAL
Note that all trigonometric functions use radian rather than degree for measuring angles. For function ATAN(x), x must be in (-PI/2, PI/2). For ASIN(x) and ACOS(x), x must be in [-1,1]. ●
Conversion functions:
Function
Meaning
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/funct.html (1 of 3)8/5/2006 8:03:18 PM
Arg. Type
Return Type
Fortran Intrinsic Functions
●
INT(x)
integer part x
REAL
INTEGER
NINT(x)
nearest integer to x
REAL
INTEGER
FLOOR(x)
greatest integer less than or equal to x
REAL
INTEGER
FRACTION (x)
the fractional part of x
REAL
REAL
REAL(x)
convert x to REAL
INTEGER
REAL
Other functions:
Function MAX(x1, x2, ..., xn)
Meaning maximum of x1, x2, ... xn
MIN(x1, x2, ..., xn) minimum of x1, x2, ... xn MOD(x,y)
remainder x - INT(x/y) *y
Arg. Type
Return Type
INTEGER INTEGER REAL
REAL
INTEGER INTEGER REAL
REAL
INTEGER INTEGER REAL
REAL
Functions in an Expression: ● ●
●
Functions have higher priority than any arithmetic operators. All arguments of a function can be expressions. These expressions are evaluated first and passed to the function for computing the function value. The returned function value is treated as a value in the expression.
An Example: The example below has three initialized variables A, B and C. The result is computed and saved into uninitialized variable R. REAL REAL
:: ::
A = 1.0, B = -5.0, C = 6.0 R
R = (-B + SQRT(B*B - 4.0*A*C))/(2.0*A) The following uses brackets to indicated the order of evaluation: (-B + SQRT(B*B - 4.0*A*C))/(2.0*A) --> ([-B] + SQRT(B*B - 4.0*A*C))/(2.0*A)
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/funct.html (2 of 3)8/5/2006 8:03:18 PM
Fortran Intrinsic Functions
--> --> --> --> --> --> --> --> --> --> --> --> --> --> -->
(5.0 + SQRT(B*B - 4.0*A*C))/(2.0*A) (5.0 + SQRT([B*B] - 4.0*A*C))/(2.0*A) (5.0 + SQRT(25.0 - 4.0*A*C))/(2.0*A) (5.0 + SQRT(25.0 - [4.0*A]*C))/(2.0*A) (5.0 + SQRT(25.0 - 4.0*C))/(2.0*A) (5.0 + SQRT(25.0 - [4.0*C))/(2.0*A) (5.0 + SQRT(25.0 - 24.0))/(2.0*A) (5.0 SQRT([25.0 - 24.0]))/(2.0*A) (5.0 + SQRT(1.0))/(2.0*A) (5.0 + 1.0)/(2.0*A) ([5.0 + 1.0])/(2.0*A) 6.0/(2.0*A) 6.0/([2.0*A]) 6.0/2.0 3.0
Therefore, R receives 3.0.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/funct.html (3 of 3)8/5/2006 8:03:18 PM
Listed-Directed Input: The READ Statement
Listed-Directed Input: The READ Statement List-directed input is carried out with the Fortran READ statements. The READ statement can read input values into a set of variables from the keyboard. The READ statement has the following forms: READ(*,*) READ(*,*)
var1, var2, ..., varn
The first form starts with READ(*,*), followed by a list of variable names, separated by commas. The computer will read values from the keyboard successively and puts the value into the variables. The second form only has READ(*,*), which has a special meaning. ●
The following example reads in four values into variables Factor, N, Multiple and tolerance in this order. INTEGER REAL
:: ::
READ(*,*) ●
Factor, N Multiple, tolerance Factor, N, Multiple, tolerance
The following example reads in a string into Title, followed by three real numbers into Height, Length and Area. CHARACTER(LEN=10) REAL READ(*,*)
:: Title :: Height, Length, Area
Title, Height, Length, Area
Preparing Input Data: Preparing input data is simple. Here are the rules: ●
If a READ statement needs some input values, start a new line that contains the input. Make sure the type of the input value and the type of the corresponding variable are the same. The input data values must be separated by space or commas. For the following READ CHARACTER(LEN=5) REAL INTEGER READ(*,*)
:: Name :: height, length :: count, MaxLength
Name, height, count, length, MaxLength
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/read-1.html (1 of 3)8/5/2006 8:03:21 PM
Listed-Directed Input: The READ Statement
The input data may look like the following: "Smith"
100.0
25
123.579
10000
Note that all input data are on the same line and separated with spaces. After reading in this line, the contents of the variables are Name height count length MaxLength ●
"Smith" 100.0 25 123.579 100000
Input values can be on several lines. As long as the number of input values and the number of variables in the corresponding READ agree, the computer will search for the input values. Thus, the following input should produce the same result. Note that even blank lines are allowed in input. "Smith"
100.0
25 123.579 10000 ●
The execution of a READ always starts searching for input values with a new input line. INTEGER
::
READ(*,*) READ(*,*) READ(*,*)
I, J, K, L, M, N
I, J K, L, M N
If the above READstatements are used to read the following input lines, 100 200 300 400 500 600
●
then I, J, K, L, Mand Nwill receive 100, 200, 300, 400, 500 and 600, respectively. Consequently, if the number of input values is larger than the number of variables in a READ statement, the extra values will be ignored. Consider the following: INTEGER READ(*,*) READ(*,*)
::
I, J, K, L, M, N I, J, K L, M, N
If the input lines are 100
200
300
400
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/read-1.html (2 of 3)8/5/2006 8:03:21 PM
Listed-Directed Input: The READ Statement
500 900
●
600
700
800
Variables I, Jand Kreceive 100, 200 and 300, respectively. Since the second READstarts with a new line, L, Mand Nreceive 500, 600 and 700, respectively. 400 on the first input line is lost. The next READwill start reading with the third line, picking up 900. Hence, 800 is lost. A limited type conversion is possible in a READ statement. If the input value is an integer and the corresponding variable is of REAL type, the input integer will be convert to a real number. But, if the input value is a real number and the corresponding variable is of INTEGER type, an error will occur.
●
The length of the input string and the length of the corresponding CHARACTER variable do not have to be equal. If they are not equal, truncation or padding with spaces will occur as discussed in the PARAMETER attribute page. Finally, a READ without a list of variables simply skips a line of input. Consider the following: INTEGER READ(*,*) READ(*,*) READ(*,*)
::
P, Q, R, S P, Q R, S
If the input lines are 100 400 700
200 500 800
300 600 900
The first READreads 100 and 200 into Pand Qand 300 is lost. The second READstarts with a new input line, which is the second one. It does not read in anything. The third READstarts with the third line and reads 700 and 800 into Rand S. As a result, the three input values (i.e., 400, 500 and 600) are all lost. The third value on the third line, 900, is also lost.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/read-1.html (3 of 3)8/5/2006 8:03:21 PM
Listed-Directed Output: The WRITE Statement
Listed-Directed Output: The WRITE Statement Listed-directed output is carried with the Fortran WRITE statement. The WRITE statement can display the results of a set of expressions and character strings. In general, WRITE displays the output on the screen. The WRITE statement has the following forms: WRITE(*,*) WRITE(*,*)
exp1, exp2, ..., expn
The first form starts with WRITE(*,*), followed by a list of arithmetic expressions or character strings, separated by commas. The computer will evaluate the arithmetic expressions and displays the results. Note that if a variable does not contain a value, its displayed result is unpredictable. The second form only has WRITE(*,*), which has a special meaning. ●
The following example displays the values of four variables on screen: INTEGER REAL
:: ::
WRITE(*,*) ●
Factor, N Multiple, tolerance Factor, N, Multiple, tolerance
The following example displays the string content of Title, followed by the result of (Height + Length) * Area. CHARACTER(LEN=10) REAL WRITE(*,*)
:: Title :: Height, Length, Area
Title, (Height + Length) * Area
There are some useful rules: ● ●
Each WRITE starts with a new line. Consequently, the second form in which the WRITE does not have a list of expressions just displays a blank line. INTEGER :: REAL :: CHARACTER(LEN=*), PARAMETER ::
Target Angle, Time = IS = UNIT =
Distance "The time to hit target " " is " " sec."
Target = 10 Angle = 20.0 Distance = 1350.0 WRITE(*,*) 'Angle = ', Angle WRITE(*,*) 'Distance = ', Distance WRITE(*,*) WRITE(*,*) Time, Target, IS, Angle * Distance, UNIT
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/write-1.html (1 of 2)8/5/2006 8:03:22 PM
& &
Listed-Directed Output: The WRITE Statement
This example may produce the following result: Angle = 20.0 Distance = 1350.0 The time to hit target 10 is 27000sec. The blank line is generated by the third WRITE. The above example uses assumed length specifier (i.e., LEN=*) and continuation lines (i.e., symbol &). ●
If there are too many results that cannot be fit into a single line, the computer will display remaining results on the second, the third line and so on.
Output Format: There is nothing to worry about the output format. The computer will use the best way to display the results. In other words, integers and real numbers will be displayed as integers and real numbers. But, only the content of a string will be displayed. The computer will also guarantee that all significant digits will be shown so that one does not have to worry how many positions should be used for displaying a number. The consequence is that displaying a good-looking table is a challenge. This will be discussed in FORMAT statement.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/write-1.html (2 of 2)8/5/2006 8:03:22 PM
Programming Example: Three Programming Traps
Programming Example: Three Programming Traps Problem Statement The purpose of this program is to show you three common programming traps: ● ● ●
A**B**C is not equal to (A**B)**C. Dividing an integer with another integer always yields an integer result. In PARAMETER, assignment statement and READ, strings may be truncated if the length of the variable at the receiving end is not long enough.
Solution ! -----------------------------------------------------------! This program illustrates the following points: ! (1) The exponential trap: ! That is, A**B**C is equal to A**(B**C) rather ! than (A**B)**C. ! (2) The integer division trap: ! That is, 4/6 is ZERO in Fortran rather than ! a real number 0.666666 ! Function REAL() is used to illustrate the ! differences. ! (3) The string truncation trap: ! What if the length assigned to a CHARACTER ! is shorter than the length of the string you ! expect the identifier to have? The third part ! shows you the effect. ! -----------------------------------------------------------PROGRAM IMPLICIT
Fortran_Traps NONE
INTEGER, PARAMETER INTEGER, PARAMETER CHARACTER(LEN=5), PARAMETER CHARACTER(LEN=4), PARAMETER CHARACTER(LEN=6), PARAMETER !
:: :: :: :: ::
A O M X Y
= = = = =
2, B = 2, H = 3 4, P = 6 'Smith', N = 'TEXAS' 'Smith' 'TEXAS'
The exponential trap WRITE(*,*) WRITE(*,*) WRITE(*,*)
"First, the exponential trap:" A, ' ** ', B, ' ** ', H, ' = ', A**B**H '( ', A, ' ** ', B, ' ) **', H, ' = ', (A**B)**H
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/traps.html (1 of 3)8/5/2006 8:03:25 PM
Programming Example: Three Programming Traps
WRITE(*,*) WRITE(*,*) ! !
A, ' ** ( ', B, ' ** ', H, ' ) = ', A**(B**H)
The integer division trap. Intrinsic function REAL() converts an integer to a real number WRITE(*,*) WRITE(*,*) WRITE(*,*) WRITE(*,*) WRITE(*,*) WRITE(*,*)
!
"Second, the integer division trap:" O, ' / ', P, ' = ', O/P 'REAL( ', O, ' ) / ', P, ' = ', REAL(O)/P O, ' / REAL( ', P, ' ) = ', O/REAL(P)
The string truncation trap WRITE(*,*) WRITE(*,*) WRITE(*,*)
END PROGRAM
"Third, the string truncation trap:" 'IS ', M, ' STILL IN ', N, '?' 'IS ', X, ' STILL IN ', Y, '?' Fortran_Traps
Click here to download this program.
Program Output First, 2 ** 2 ( 2 ** 2 ** (
the exponential trap: ** 3 = 256 2 ) **3 = 64 2 ** 3 ) = 256
Second, the integer division trap: 4 / 6 = 0 REAL( 4 ) / 6 = 0.666666687 4 / REAL( 6 ) = 0.666666687 Third, the string truncation trap: IS Smith STILL IN TEXAS? IS Smit STILL IN TEXAS ?
Discussion ● ●
All names in this program are aliases of constants. Consider the first group. Variables A, B and H are aliases of 2, 2 and 3. The first WRITE computes A**B**H, which is equivalent to A**(B**H), and the result is 2**(2**3)=256. The second WRITE computes (A**B)**C and the result is (2**2)**3=64. The third WRITE computes A**(B**H) and the result is 2**(2**3)=256. Thus, it is
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/traps.html (2 of 3)8/5/2006 8:03:25 PM
Programming Example: Three Programming Traps
●
●
clear that A**B**H equal to A**(B**H). The second group illustrates the problem unique to integer division. Two integer aliases are involved, namely O and P with values 4 and 6, respectively. The first WRITE displays O/P and the result is 4/6=0 since it is an integer division. The second WRITE converts O to real with intrinsic function REAL(). Thus, in computing REAL(O)/P, the expression is REAL(4)/6, which becomes 4.0/6 and then 4.0/6.0. Thus, the result is 0.6666667. The third WRITE should give the same result. Go back to the top of this program. Alias M and N should have no problem since the length of the names and the length of the strings agree. Since the length of X is 4 and is shorter than the length of string 'Smith', X only receives the left-most 4 characters. Now take a look at Y. Since the length of Y is longer than the length of string 'TEXAS', spaces will be appended to the end to fill up to 6 characters. Thus, Y actually becomes 'TEXAS '. The output should look like the following: IS Smith STILL IN TEXAS? IS Smit STILL IN TEXAS ? On the second line, it is easily seen that the original Smithbecomes Smitand the original TEXASbecomes TEXAS_, where _indicates a space.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/traps.html (3 of 3)8/5/2006 8:03:25 PM
Programming Example: Computing Means
Programming Example: Computing Means Problem Statement Given three real numbers, its arithmetic mean (average), geometric mean and harmonic mean are defined as follows:
Write a program to compute and display the means of three REAL variables initialized with positive real values.
Solution ! ------------------------------------------------------! Computes arithmetic, geometric and harmonic means ! ------------------------------------------------------PROGRAM ComputeMeans IMPLICIT NONE REAL REAL
:: X = 1.0, Y = 2.0, Z = 3.0 :: ArithMean, GeoMean, HarmMean
WRITE(*,*) WRITE(*,*)
'Data items: ', X, Y, Z
ArithMean = (X + Y + Z)/3.0 GeoMean = (X * Y * Z)**(1.0/3.0) HarmMean = 3.0/(1.0/X + 1.0/Y + 1.0/Z) WRITE(*,*) WRITE(*,*) WRITE(*,*)
'Arithmetic mean = ', ArithMean 'Geometric mean = ', GeoMean 'Harmonic Mean = ', HarmMean
END PROGRAM ComputeMeans Click here to download this program.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/means.html (1 of 2)8/5/2006 8:03:28 PM
Programming Example: Computing Means
Program Output Data items: 1.,
2.,
3.
Arithmetic mean = 2. Geometric mean = 1.81712067 Harmonic Mean = 1.63636363
Discussion ●
● ●
●
Variables X, Y and Z are initialized in the first REAL statement, while the second declares three variables, ArithMean, GeoMean and HarmMean, for holding the result. The first WRITE statement displays the values of X, Y and Z. The second WRITE generates a blank line. In the second assignment statement that computes the geometric mean, the exponent part is 1.0/3.0 instead of 1/3, since the latter is zero. 1.0/3 and 1.0/3 also work fine. But, you should not use 0.3, since it is not equal to 1/3. The parenthesis surrounding X * Y * Z cannot be removed; otherwise, the expression X * Y * Z **(1.0/3.0) means X * Y * (Z **(1.0/3.0)) since ** has a priority higher than that of *. The parenthesis in the third assignment cannot be removed either. Why?
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/means.html (2 of 2)8/5/2006 8:03:28 PM
Programming Example: Quadratic Equation Solver
Programming Example: Quadratic Equation Solver Problem Statement Given a quadratic equation as follows:
if b*b-4*a*c is non-negative, the roots of the equation can be computed with the following formulae:
Write a program to read in the coefficients a, b and c, and compute and display the roots. You can assume that b*b - 4*a*c is always non-negative.
Solution ! --------------------------------------------------! Solve Ax^2 + Bx + C = 0 given B*B-4*A*C >= 0 ! --------------------------------------------------PROGRAM QuadraticEquation IMPLICIT NONE REAL REAL REAL !
:: a, b, c :: d :: root1, root2
read in the coefficients a, b and c WRITE(*,*) 'A, B, C Please : ' READ(*,*) a, b, c
!
compute the square root of discriminant d d
!
= SQRT(b*b - 4.0*a*c)
solve the equation
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/quad-1.html (1 of 2)8/5/2006 8:03:32 PM
Programming Example: Quadratic Equation Solver
root1 = (-b + d)/(2.0*a) root2 = (-b - d)/(2.0*a) !
! first root ! second root
display the results WRITE(*,*) WRITE(*,*)
END PROGRAM
'Roots are ', root1, ' and ', root2 QuadraticEquation
Click here to download this program.
Program Output A, B, C Please : 1.0 -5.0 3.0 Roots are 4.30277538 and 0.697224379 The input to the above problem consists of three real numbers, 1.0, -5.0 and 3.0, and the computed roots are 4.30277538 and 0.697224379.
Discussion ●
The WRITE displays a message like this A, B, C Please :
●
●
●
After displaying this message, the computer executes READ. Since there is no input value, it will wait until the user types in three real values and hits the Returnkey. Then, these values are stored in a, band c. The first assignment statement computes the square root of the discriminant (i.e., b*b - 4.0*a*c) and stores it into variable d. The roots are computed with the second and third assignments. Note that the parenthesis surrounding 2.0*a cannot be removed; otherwise, it is equivalent to ((-b + d)/2.0)*a, which is wrong. The last two WRITE statements display the roots.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/quad-1.html (2 of 2)8/5/2006 8:03:32 PM
Programming Example: The Length of a Parabola Segment
Programming Example: The Length of a Parabola Segment Problem Statement Given base b and height h, the length of a special segment on a parabola can be computed as follows:
Write a program to read in the values of base and height, and use the above formula to compute the length of the parabola segment. Note that both base and height values must be positive.
Solution ! ----------------------------------------------------------! Calculate the length of a parabola given height and base. * ! ----------------------------------------------------------PROGRAM ParabolaLength IMPLICIT NONE REAL REAL
:: Height, Base, Length :: temp, t
WRITE(*,*) READ(*,*)
'Height of a parabola : ' Height
WRITE(*,*) READ(*,*)
'Base of a parabola Base
: '
! ... temp and t are two temporary variables t = 2.0 * Height temp = SQRT(t**2 + Base**2) Length = temp + Base**2/t*LOG((t + temp)/Base) WRITE(*,*) WRITE(*,*) WRITE(*,*) WRITE(*,*) END PROGRAM
'Height = ', Height 'Base = ', Base 'Length = ', Length ParabolaLength
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/p-length.html (1 of 2)8/5/2006 8:03:39 PM
Programming Example: The Length of a Parabola Segment
Click here to download this program.
Program Output Height of a parabola : 100.0 Base of a parabola 78.5
:
Height = 100. Base = 78.5 Length = 266.149445 The input values for Height and Base are 100.0 and 78.5, respectively. The computed length is 266.149445.
Discussion ●
●
●
●
The values of base and height will be stored in REAL variables Base and Height, respectively. Length will be used to store the parabola segment length. Since the content in the square root is used twice, it would be more convenient to save the result in a variable. This value will be stored in temp. Since 2h also appears a few times, variable t is used to store this value. After reading in Height and Base, 2.0 * Height is computed and stored in t with the first assignment. Then, the second assignment computes the content in the square root and stores the result into temp. The third assignment compute the segment length and stores the result into Length. Note that intrinsic function LOG () is used. The four WRITE statements display the input and the results.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/p-length.html (2 of 2)8/5/2006 8:03:39 PM
Programming Example: Projectile Motion
Programming Example: Projectile Motion Problem Statement This program computes the position (x and y coordinates) and the velocity (magnitude and direction) of a projectile, given t, the time since launch, u, the launch velocity, a, the initial angle of launch (in degree), and g=9.8, the acceleration due to gravity. The horizontal and vertical displacements are given by the following formulae:
The horizontal and vertical components of the velocity vector are computed as
and the magnitude of the velocity vector is
Finally, the angle between the ground and the velocity vector is determined by the formula below:
Write a program to read in the launch angle a, the time since launch t, and the launch velocity u, and compute the position, the velocity and the angle with the ground.
Solution ! ! ! ! ! !
-------------------------------------------------------------------Given t, the time since launch, u, the launch velocity, a, the initial angle of launch (in degree), and g, the acceleration due to gravity, this program computes the position (x and y coordinates) and the velocity (magnitude and direction) of a projectile. --------------------------------------------------------------------
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/projectile.html (1 of 3)8/5/2006 8:03:42 PM
Programming Example: Projectile Motion
PROGRAM Projectile IMPLICIT NONE REAL, PARAMETER :: g = 9.8 REAL, PARAMETER :: PI = 3.1415926
! acceleration due to gravity ! you knew this. didn't you
REAL REAL REAL REAL REAL REAL REAL REAL REAL
! ! ! ! ! ! ! ! !
:: :: :: :: :: :: :: :: ::
READ(*,*) Angle X Y Vx Vy V Theta
= = = = = = =
Angle Time Theta U V Vx Vy X Y
launch angle in degree time to flight direction at time in degree launch velocity resultant velocity horizontal velocity vertical velocity horizontal displacement vertical displacement
Angle, Time, U
Angle * PI / 180.0 ! convert to radian U * COS(Angle) * Time U * SIN(Angle) * Time - g*Time*Time / 2.0 U * COS(Angle) U * SIN(Angle) - g * Time SQRT(Vx*Vx + Vy*Vy) ATAN(Vy/Vx) * 180.0 / PI
WRITE(*,*) WRITE(*,*) WRITE(*,*) WRITE(*,*) END PROGRAM
'Horizontal displacement 'Vertical displacement 'Resultant velocity 'Direction (in degree)
: : : :
', ', ', ',
Projectile
Click here to download this program.
Program Output If the input to the program consists of the following three real values: 45.0
6.0
60.0
The program will generate the following output: Horizontal displacement Vertical displacement Resultant velocity Direction (in degree)
: : : :
254.558472 78.158432 45.4763107 -21.1030636
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/projectile.html (2 of 3)8/5/2006 8:03:42 PM
X Y V Theta
Programming Example: Projectile Motion
Discussion ● ●
● ● ● ●
The program uses Angle for the angle a, Time for t, and U for u. The READ statement reads the input. The first assignment statement converts the angle in degree to radian. This is necessary since all intrinsic trigonometric functions use radian rather than degree. Variables X and Y, which are computed in the second and third assignments, hold the displacements. The next two assignments compute the components of the velocity vector. The velocity itself is computed in the sixth assignment. Finally, the angle with ground, Theta, is computed with the last assignment. Note that ithe result is converted back to degree, since ATAN(x) returns the arc tangent value of x in radian.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/projectile.html (3 of 3)8/5/2006 8:03:42 PM
CHARACTER Operator and Substrings
CHARACTER Operator and Substrings Concatenation Operator // Fortran has only one character operator, the concatenation operator //. The concatenation operator cannot be used with arithmetic operators. Given two strings, s1 and s2 of lengths m and n, respectively, the concatenation of s1 and s2, written as s1 // s2, contains all characters in string s1, followed by all characters in string s2. Therefore, the length of s1 // s2 is m +n. Consider the following statements: CHARACTER(LEN=4) CHARACTER(LEN=6) CHARACTER(LEN=10) Ans1 Ans2 Ans3 Ans4 ●
●
● ●
= = = =
:: John = "John", Sam = "Sam" :: Lori = "Lori", Reagan = "Reagan" :: Ans1, Ans2, Ans3, Ans4
John // Lori Sam // Reagon Reagon // Sam Lori // Sam
Variable Ans1 contains a string "JohnLori**", where * denotes a space. These two spaces come from variable Lori since its content is "Lori**". Variable Ans2 contains a string "Sam Reagan". The space in the string comes from variable Sam since its content is "Sam*", where, as above, * denotes a space. Variable Ans3 contains a string "ReaganSam*". Variable Ans4 contains a string "Lori**Sam*".
Substrings A consecutive part of a string is called a substring. One can append the extent specifier at the end of a CHARACTER variable to indicate a substring. An extent specifier has a form of ( integer-exp1 : integer-exp2 ) It starts with a (, followed by an integer expression, followed by a colon :, followed by another integer expression, followed by ). The first integer indicates the first position of the substring, while the second integer indicates the last position of the substring. Therefore, (3:5) means the substring consists of the third, fourth and fifth characters. If the content of variable String is "abcdefghijk", then String(3:5) is a string "cde". If the first integer expression is missing, the value is assumed to be 1. If the second integer expression is missing, the value is assumed to be the last character of the string. Continue with the example in previous paragraph. String(:4) is string "abcd". String(2+5:) is string "ghijk".
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/char-opr.html (1 of 4)8/5/2006 8:03:46 PM
CHARACTER Operator and Substrings
As a good programming practice, the value of the first integer expression should be greater than or equal to 1, and the value of the second integer expression should be less than of equal to the length of the string. A string variable with an extent specifier can be used on the left-hand side of an assignment. Its meaning is assigning the string content on the right-hand side into the substring part of the string variable. Let the content of a string variable LeftHand of length 10 be "1234567890". The following are a few examples: ● ● ● ● ●
●
LeftHand(3:5) = "abc": the new content of LeftHand is "12abc67890". LeftHand(1:6) = "uvwxyz": the new content of LeftHand is "uvwxyz7890". LeftHand(:6) = "uvzxyz": the result is identical to the previous example. LeftHand(4:) = "lmnopqr": the new content of LeftHand is "123lmnopqr". LeftHand(3:8) = "abc": the new content of LeftHand is "12abc***90", where * denotes a space. Note that since LeftHand(3:8) consists of 6 character positions and "abc" has only three characters, the remaining will be filled with spaces. LeftHand(4:7) = "lmnopq": the new content of LeftHand is "123lmno890". It is due to truncation.
Example ! ---------------------------------------------------------------! This program uses DATE_AND_TIME() to retrieve the system date ! and the system time. Then, it converts the date and time ! information to a readable format. This program demonstrates ! the use of concatenation operator // and substring ! ---------------------------------------------------------------PROGRAM DateTime IMPLICIT NONE CHARACTER(LEN = 8) CHARACTER(LEN = 4)
:: DateINFO :: Year, Month*2, Day*2
CHARACTER(LEN = 10) :: TimeINFO, PrettyTime*12 CHARACTER(LEN = 2) :: Hour, Minute, Second*6 CALL ! ! !
! ccyymmdd
! hhmmss.sss
DATE_AND_TIME(DateINFO, TimeINFO)
decompose DateINFO into year, month and day. DateINFO has a form of ccyymmdd, where cc = century, yy = year mm = month and dd = day Year = DateINFO(1:4) Month = DateINFO(5:6) Day = DateINFO(7:8) WRITE(*,*) WRITE(*,*) WRITE(*,*) WRITE(*,*)
'Date information -> ', DateINFO ' Year -> ', Year ' Month -> ', Month ' Day -> ', Day
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/char-opr.html (2 of 4)8/5/2006 8:03:46 PM
CHARACTER Operator and Substrings
! ! !
decompose TimeINFO into hour, minute and second. TimeINFO has a form of hhmmss.sss, where h = hour, m = minute and s = second Hour = TimeINFO(1:2) Minute = TimeINFO(3:4) Second = TimeINFO(5:10) PrettyTime = Hour // ':' // Minute // ':' // Second WRITE(*,*) WRITE(*,*) WRITE(*,*) WRITE(*,*) WRITE(*,*) WRITE(*,*)
!
'Time Information -> ', TimeINFO ' Hour -> ', Hour ' Minite -> ', Minute ' Second -> ', Second ' Pretty Time -> ', PrettyTime
the substring operator can be used on the left-hand side. PrettyTime = ' ' PrettyTime( :2) = PrettyTime(3:3) = PrettyTime(4:5) = PrettyTime(6:6) = PrettyTime(7: ) =
Hour ':' Minute ':' Second
WRITE(*,*) WRITE(*,*)
Pretty Time -> ', PrettyTime
END PROGRAM
' DateTime
Click here to download this program.
Program Output Date information Year Month Day
-> -> -> ->
19970811 1997 08 11
Time Information Hour Minite Second Pretty Time
-> -> -> -> ->
010717.620 01 07 17.620 01:07:17.620
Pretty Time -> 01:07:17.620
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/char-opr.html (3 of 4)8/5/2006 8:03:46 PM
CHARACTER Operator and Substrings
Discussion ●
●
Subroutine DATE_AND_TIME() returns the date of time and day information into two character arguments. The first one, DateINFO, must have a length of at least 8. The returned value is in the form of ccyymmdd, where cc gives the century, yy the year, mm the month, and dd the day. If today is August 11, 1997, the call to this subroutine returns a string of eight characters "19970811" The second argument, TimeINFO, will receive a string of 12 characters with a form of hhmmss.sss, where hh gives the hour value, mm the minute value, and ss.sss the second value. Thus, if the time this subroutine is called is 1 after 7 minutes and 17.620 seconds, the returned value is "010717.620"
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap02/char-opr.html (4 of 4)8/5/2006 8:03:46 PM
Selective Execution
Selective Execution Select the topics you wish to review: Selective Execution LOGICAL Type and Variables LOGICAL Input and Output Relational Operators LOGICAL Operators and Expressions IF-THEN-ELSE-END IF Statement Form 1: IF-THEN-ELSE-END IF Form 2: IF-THEN-END IF Form 3: Logical IF Programming Example 1: Quadratic Equation Solver Programming Example 2: Final Mark Computation Programming Example 3: Heron's Formula for Computing Triangle Area Nested IF-THEN-ELSE-END IF IF-THEN-ELSE IF-END IF Programming Examples: Quadratic Equation Solver: Again Quadratic Equation Solver: Revisited Sort Three Numbers SELECT CASE Statement Programming Example 1: Computing Letter Grade Programming Example 2: Character Testing Download my course overheads
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/select.html8/5/2006 8:04:19 PM
LOGICAL Type and Variables
LOGICAL Type and Variables LOGICAL values are either true or false. In Fortran, they must be written as .TRUE. and .FALSE. Note that the two periods surrounding TRUE and FALSE must be there; otherwise, they become identifiers. A variable that can hold one of the logical values is a logical variable and it is of type LOGICAL. To declare a LOGICAL variable, do it as what you did for INTEGER and REAL variables. But, use the type name LOGICAL instead. LOGICAL constants can have aliases declared with the PARAMETER attribute. LOGICAL variables can be initialized when they are declared and can be assigned a logical value. However, a LOGICAL variable can only hold a logical value. Putting a value of any other type (e.g., INTEGER or REAL) into a LOGICAL variable will cause an error. The following are examples: ●
Answer, Condition, Test, Value and Yes_and_No are LOGICAL variables that can hold either .TRUE. or . FALSE.: LOGICAL LOGICAL
●
:: Answer, Condition, Test :: Value, Yes_and_No
LOGICAL identifiers Answer and Condition are aliases of .TRUE. and .FALSE., respectively: LOGICAL, PARAMETER :: Answer = .TRUE., Condition = .FALSE.
●
LOGICAL variables Test and PreTest are initialized to .TRUE. and .FALSE., respectively: LOGICAL
●
:: Test = .TRUE., PreTest = .FALSE.
LOGICAL variables Cond_1, Cond_2 and Total are assigned with .TRUE., .TRUE. and .FALSE., respectively: LOGICAL
:: Cond_1, Cond_2, Total
Cond_1 = .TRUE. Cond_2 = .TRUE. Total = .FALSE.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/log-type.html8/5/2006 8:04:23 PM
LOGICAL Input and Output
LOGICAL Input and Output When using WRITE(*,*) to display a LOGICAL value, Fortran displays .TRUE. and .FALSE. with T and F, respectively. When preparing input for READ(*,*), use T and F for .TRUE. and .FALSE., respectively.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/log-io.html8/5/2006 8:04:25 PM
Relational Operators
Relational Operators There are six relational operators: ● ● ● ● ● ●
< : less than : greater than >= : greater than or equal to == : equal to /= : not equal to
Here are important rules: ●
● ●
Each of these six relational operators takes two operands. These two operands must both be arithmetic or both be strings. For arithmetic operands, if they are of different types (i.e., one INTEGER and the other REAL), the INTEGER operand will be converted to REAL. The outcome of a comparison is a LOGICAL value. For example, 5 /= 3 is .TRUE. and 7 + 3 >= 20 is .FALSE. All relational operators have equal priority and are lower than those of arithmetics operators as shown in the table below: Type Arithmetic
Operator
Associativity
**
right to left
*
/
left to right
+
-
left to right
Relational < >= ==
/ =
none
This means that a relational operator can be evaluated only if its two operands have been evaluated. For example, in a + b /= c*c + d*d
●
expressions a+b and c*c + d*d are evaluated before the relational operator /= is evaluated. If you are not comfortable in writing long relational expressions, use parenthesis. Thus, 3.0*SQRT(Total)/(Account + Sum) - Sum*Sum >= Total*GNP - b*b is equivalent to the following: (3.0*SQRT(Total)/(Account + Sum) - Sum*Sum) >= (Total*GNP - b*b)
●
Although a < b < c is legal in mathematics, you cannot write comparisons this way in Fortran. The meaning of this expression is a < b and b < c. You should use logical operator to achieve this.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/relational.html (1 of 4)8/5/2006 8:04:29 PM
Relational Operators
Examples ● ●
●
3**2 + 4**2 == 5**2 is .TRUE. If the values of REAL variables a, b and c are 1.0, 2.0 and 4.0, respectively, then b*b - 4.0*a*c >= 0.0 is equivalent to 2.0*2.0 - 4.0*1.0*4.0 >= 0.0, which evaluates to -12.0 >= 0.0. Thus, the result is .FALSE. If REAL variables x and y have values 3.0 and 7.0, and INTEGER variables p and q have values 6 and 2, what is the result of x*x - y*y + 2.0*x*y /= p*q + p**3 - q**3? x*x - y*y + 2.0*x*y /= p*q + p**3 - q**3 --> 3.0*3.0 - 7.0*7.0 + 2.0*3.0*7.0 /= 6*2 + 6**3 - 2**3 --> [3.0*3.0] - 7.0*7.0 + 2.0*3.0*7.0 /= 6*2 + 6**3 - 2**3 --> 9.0 - 7.0*7.0 + 2.0*3.0*7.0 /= 6*2 + 6**3 - 2**3 --> 9.0 - [7.0*7.0] + 2.0*3.0*7.0 /= 6*2 + 6**3 - 2**3 --> 9.0 - 49.0 + 2.0*3.0*7.0 /= 6*2 + 6**3 - 2**3 --> [9.0 - 49.0] + 2.0*3.0*7.0 /= 6*2 + 6**3 - 2**3 --> -40.0 + 2.0*3.0*7.0 /= 6*2 + 6**3 - 2**3 --> -40.0 + [2.0*3.0]*7.0 /= 6*2 + 6**3 - 2**3 --> -40.0 + 6.0*7.0 /= 6*2 + 6**3 - 2**3 --> -40.0 + [6.0*7.0] /= 6*2 + 6**3 - 2**3 --> -40.0 + 42.0 /= 6*2 + 6**3 - 2**3 --> [-40.0 + 42.0] /= 6*2 + 6**3 - 2**3 --> 2.0 /= 6*2 + 6**3 - 2**3 --> 2.0 /= [6*2] + 6**3 - 2**3 --> 2.0 /= 12 + 6**3 - 2**3 --> 2.0 /= 12 + [6**3] - 2**3 --> 2.0 /= 12 + 216 - 2**3 --> 2.0 /= [12 + 216] - 2**3 --> 2.0 /= 228 - 2**3 --> 2.0 /= 228 - [2**3] --> 2.0 /= 228 - 8 --> 2.0 /= [228 - 8] --> 2.0 /= [220] --> 2.0 /= 220.0 --> .TRUE. In the above, please note the left-to-right evaluation order and the type conversion making 220 to 220.0 before carrying out /=
Comparing CHARACTER Strings Characters are encoded. Different standards (e.g. BCD, EBCDIC and ASCII) may have different encoding schemes. To write a program that can run on all different kind of computers and get the same comparison results, one can only assume the following ordering sequences: A < B < C < D < E < F < G < H < I < J < K < L < M
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/relational.html (2 of 4)8/5/2006 8:04:29 PM
Relational Operators
< N < O < P < Q < R < S < T < U < V < W < X < Y < Z a < b < c < d < e < f < g < h < i < j < k < l < m < n < o < p < q < r < s < t < u < v < w < x < y < z 0 < 1 < 2 < 3 < 4 < 5 < 6 < 7 < 8 < 9 If you compare characters in different sequences such as 'A' < 'a' and '2' >= 'N', you are asking for trouble since different encoding methods may produce different answers. Moreover, do not assume there exists a specific order among upper and lower case letters, digits, and special symbols. Thus, '+' = '%', 'u' > '$', and '8' >= '?' make no sense. However, you can always compare if two characters are equal or not equal. Hence, '*' /= '9', 'a' == 'B' and '8' == 'b' are perfectly fine. Here is the method for comparing two strings: ● ● ●
●
The comparison always starts at the first character and proceeds from left to right. If the two corresponding characters are equal, then proceed to the next pair of characters. Otherwise, the string containing the smaller character is considered to be the smaller one. And, the comparison halts. During the process comparison, if ❍ both strings have consumed all of their characters, they are equal since all of their corresponding characters are equal. ❍ otherwise, the shorter string is considered to be the smaller one.
Examples ●
Compare "abcdef" and "abcefg" a b c d e f = = = < a b c e f g
●
The first three characters of both strings are equal. Since 'd' of the first string is smaller than 'e' of the second, "abcdef" < "abcefg" holds. Compare "01357" and "013579" 0 1 3 5 7 = = = = = 0 1 3 5 7 9
●
Since all compared characters are equal and the first string is shorter, "01357" < "013579" holds. What is the result of "DOG" < "FOX"? D O G < F O X
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/relational.html (3 of 4)8/5/2006 8:04:29 PM
Relational Operators
The first character (i.e., 'D' < 'F') determines the outcome. That is, "DOG" < "FOX" yields .TRUE.
A Special Note The priority of all six relational operators is lower than the string concatenation operator //. Therefore, if a relational expression involves //, then all string concatenations must be carried out before evaluating the comparison operator. Here is an example: "abcde" // "xyz" < "abc" // ("dex" // "ijk") --> ["abcde" // "xyz"] < "abc" // ("dex" // "ijk") --> "abcdexyz" < "abc" // ("dex" // "ijk") --> "abcdexyz" < "abc" // (["dex" // "ijk"]) --> "abcdexyz" < "abc" // ("dexijk") --> "abcdexyz" < "abc" // "dexijk" --> "abcdexyz" < ["abc" // "dexijk"] --> "abcdexyz" < "abcdexijk" --> .FALSE.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/relational.html (4 of 4)8/5/2006 8:04:29 PM
LOGICAL Operators and Expressions
LOGICAL Operators and Expressions Fortran has five LOGICAL operators that can only be used with expressions whose results are logical values (i.e., .TRUE. or .FALSE.). All LOGICAL operators have priorities lower than arithmetic and relational operators. Therefore, if an expression involving arithmetic, relational and logical operators, the arithmetic operators are evaluated first, followed by the relational operators, followed by the logical operators. These five logical operators are ● ● ● ● ●
.NOT. : logical not .AND. : logical and .OR. : logical or .EQV. : logical equivalence .NEQV. : logical not equivalence
The following is a table of these operators, including there priority and associativity. Type Arithmetic
Operator
Associativity
**
right to left
*
/
left to right
+
-
left to right
Relational < >= ==
Logical
/ =
none
.NOT.
right to left
.AND.
left to right
.OR.
left to right
.EQV.
.NEQV.
left to right
Truth Tables The evaluation of logical expressions is determined by truth tables. Let us start with the .NOT. operator. Operand
Result
. . .TRUE. NOT. FALSE. .FALSE. .TRUE. Note that .NOT. is a unary operator. Therefore, .NOT. a yields .TRUE. (resp., .FALSE.) if the value of LOGICAL variable a is .FALSE. (resp., .TRUE.). http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/logical.html (1 of 5)8/5/2006 8:04:39 PM
LOGICAL Operators and Expressions
The following is the truth table of .AND.: .AND. .TRUE.
.TRUE. .FALSE .TRUE.
. FALSE.
. . . FALSE. FALSE. FALSE. Therefore, the result of logical expression a .AND. b is .TRUE. if and only if both operands a and b are .TRUE.. In all other cases, the result is always .FALSE.
The following is the truth table of .OR.:
.OR.
. .FALSE TRUE.
.TRUE.
. .TRUE. TRUE.
. . . FALSE. TRUE. FALSE. Therefore, the result of logical expression a .OR. b is .FALSE. if and only if both operands a and b are .FALSE.. In all other cases, the result is always .TRUE. In other words, if one of the two operands of the .OR. operator is .TRUE., the result is .TRUE.
The following is the truth table of .EQV.: .EQV. .TRUE.
.TRUE. .FALSE .TRUE.
. FALSE.
. . .TRUE. FALSE. FALSE. Therefore, the result of logical expression a .EQV. b is .TRUE. if and only if both operands a and b have the same value (i. e., both are .TRUE. or both are .FALSE.). As mentioned in relational expressions, relational operators can only compare arithmetic values and cannot be used to compare logical values. To compare if two logical values are equal, use .EQV.
The following is the truth table of .NEQV.: .NEQV. .TRUE. .FALSE
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/logical.html (2 of 5)8/5/2006 8:04:39 PM
LOGICAL Operators and Expressions
.TRUE.
. .TRUE. FALSE.
. . .TRUE. FALSE. FALSE. Therefore, the result of logical expression a .NEQV. b is .TRUE. if and only if both operands a and b do not have the same value. As mentioned in relational expressions, relational operators can only compare arithmetic values and cannot be used to compare logical values. To compare if two logical values are not equal, use .NEQV. Note that .NEQV is the opposite of . EQV.. Hence, to test if logical variables x and y have different values, one can use .NOT. (x .EQV. y). Here, if x and y have the same value, x .EQV. y is .TRUE. and .NOT. (x .EQV. y) is .FALSE. On the other hand, if x and y have different values, x .EQV. y is .FALSE. and .NOT. (x .EQV. y) is .TRUE.
Priority The priority of .NOT. is the highest, followed by .AND., followed by .OR., followed by .EQV. and .NEQV. Note that . NOT. is right associative, while the other four are left associative. Here are some examples: ●
Let LOGICAL variables Something and Another have values .TRUE. and .FALSE., respectively. .NOT.
Something .AND. Another --> .NOT. .TRUE. .AND. .FALSE. --> [.NOT. .TRUE.] .AND. .FALSE. --> .FALSE. .AND. .FALSE. --> .FALSE.
In the above, since .NOT.has the highest priority, it is evaluated first. Now, look at the following example: .NOT.
(Something .AND. Another) --> .NOT. (.TRUE. .AND. .FALSE.) --> .NOT. ([.TRUE. .AND. .FALSE.]) --> .NOT. .FALSE. --> .TRUE.
●
Let LOGICAL variables a, b and c have values .TRUE., .TRUE. and .FALSE., respectively. .NOT.
a --> --> --> --> --> --> --> -->
.OR. .NOT. b .AND. c .NOT. .TRUE. .OR. .NOT. .TRUE. .AND. .FALSE. [.NOT. .TRUE.] .OR. .NOT. .TRUE. .AND. .FALSE. .FALSE. .OR. .NOT. .TRUE. .AND. .FALSE. .FALSE. .OR. [.NOT. .TRUE.] .AND. .FALSE. .FALSE. .OR. .FALSE. .AND. .FALSE. .FALSE. .OR. [.FALSE. .AND. .FALSE.] .FALSE. .OR. .FALSE. .FALSE.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/logical.html (3 of 5)8/5/2006 8:04:39 PM
LOGICAL Operators and Expressions ●
Let INTEGER variable n have a value of 4: n**2 + 1 --> --> --> --> --> --> --> --> --> --> --> -->
> 10 .AND. .NOT. n < 3 4**2 + 1 > 10 .AND. .NOT. 4 [4**2] + 1 > 10 .AND. .NOT. 16 + 1 > 10 .AND. .NOT. 4 < [16 + 1] > 10 .AND. .NOT. 4 17 > 10 .AND. .NOT. 4 < 3 [17 > 10] .AND. .NOT. 4 < 3 .TRUE. .AND. .NOT. 4 < 3 .TRUE. .AND. .NOT. [4 < 3] .TRUE. .AND. .NOT. .FALSE .TRUE. .AND. [.NOT. .FALSE] .TRUE. .AND. .TRUE. .TRUE.
< 3 4 < 3 3 < 3
Note that the above expression, if you like, can be rewritten with parentheses as follows: (n**2 + 1 > 10) .AND. .NOT. (n < 3) ●
Let INTEGER variables m, n, x and y have values 3, 5, 4 and 2, respectively: .NOT. (m --> --> --> --> --> --> --> --> --> --> --> --> --> --> --> --> -->
> n .AND. x < y) .NEQV. (m = y) .NOT. (3 > 5 .AND. 4 < 2) .NEQV. (3 = 2) .NOT. ([3 > 5] .AND. 4 < 2) .NEQV. (3 = 2) .NOT. (.FALSE. .AND. 4 < 2) .NEQV. (3 = 2) .NOT. (.FALSE. .AND. [4 < 2]) .NEQV. (3 = 2) .NOT. (.FALSE. .AND. .FALSE.) .NEQV. (3 = 2) .NOT. ([.FALSE. .AND. .FALSE.]) .NEQV. (3 = 2) .NOT. (.FALSE.) .NEQV. (3 = 2) [.NOT. .FALSE.] .NEQV. (3 = 2) .TRUE. .NEQV. (3 = 2) .TRUE. .NEQV. ([3 = 2) .TRUE. .NEQV. (.TRUE. .AND. 4 >= 2) .TRUE. .NEQV. (.TRUE. .AND. [4 >= 2]) .TRUE. .NEQV. (.TRUE. .AND. .TRUE.) .TRUE. .NEQV. ([.TRUE. .AND. .TRUE.]) .TRUE. .NEQV. (.TRUE.) .TRUE. .NEQV. .TRUE. .FALSE.
Assignments The result of a logical expression can be assigned into a LOGICAL variable. Note that only logical values can be put into LOGICAL variables. The follow assignments save the results of the examples into LOGICAL variables: LOGICAL :: Result1, Result2, Result3, Result4
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/logical.html (4 of 5)8/5/2006 8:04:39 PM
LOGICAL Operators and Expressions
Result1 Result2 Result3 Result4
= = = =
.NOT. Something .AND. Another .NOT. a .OR. .NOT. b .AND. c (n**2 + 1 > 10) .AND. .NOT. (n < 3) .NOT. (m > n .AND. x < y) .NEQV. (m = y)
Thus, Result1, Result2, Result3 and Results receive .FALSE., .FALSE., .TRUE. and .FALSE., respectively.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/logical.html (5 of 5)8/5/2006 8:04:39 PM
IF-THEN-ELSE-END IF
IF-THEN-ELSE-END IF The most general form of the IF-THEN-ELSE-END IF statement is the following: IF (logical-expression) THEN statements-1 ELSE statements-2 END IF where statements-1 and statements-2 are sequences of executable statements, and logical-expression is a logical expression. The execution of this IF-THEN-ELSE-END IF statement goes as follows: ● ● ● ●
the logical-expression is evaluated, yielding a logical value if the result is .TRUE., the statements in statements-1 are executed if the result is .FALSE., the statements in statements-2 are executed after finish executing statements in statements-1 or statements-2, the statement following END IF is executed.
Examples ●
The following code first reads in an integer into INTEGER variable Number. Then, if Number can be divided evenly by 2 (i.e., Number is a multiple of 2), the WRITE(*,*) between IF and ELSE is executed and shows that the number is even; otherwise, the WRITE(*,*) between ELSE and END IF is executed and shows that the number is odd. Function MOD(x,y) computes the remainder of x divided by y. This is the the remainder (or modulo) function INTEGER :: Number READ(*,*) Number IF (MOD(Number, 2) == 0) THEN WRITE(*,*) Number, ' is even' ELSE WRITE(*,*) Number, ' is odd' END IF
●
The following program segment computes the absolute value of X and saves the result into variable Absolute_X. Recall that the absolute value of x is x if x is non-negative; otherwise, the absolute value is -x. For example, the absolute value of 5 is 5 and the absolute value of -4 is 4=-(-4). Also note that the WRITE(*,*) statement has been intentionally broken into two lines with the continuation line symbol &. REAL
:: X, Absolute_X
X = ..... IF (X >= 0.0) THEN http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/if-then-else.html (1 of 2)8/5/2006 8:04:40 PM
IF-THEN-ELSE-END IF
Absolute_X = X ELSE Absolute_X = -X END IF WRITE(*,*) 'The absolute value of ', x, & ' is ', Absolute_X ●
The following program segment reads in two integer values into a and b and finds the smaller one into Smaller. Note that the WRITE(*,*) has also been broken into two lines. INTEGER
:: a, b, Smaller
READ(*,*) a, b IF (a b) Smaller = b Write(*,*) 'The smaller of ', a, ' and ', & b, ' is ', Smaller http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/if.html (1 of 2)8/5/2006 8:04:44 PM
Logical IF
●
In many cases, it is required to do something when certain condition is satisfied; otherwise, do nothing. This is exactly what we need the form of IF-THEN-END IF. In the following, an INTEGER variable Counter is used for counting something. When its value is a multiple of 10, a blank line is displayed. INTEGER :: Counter IF (MOD(Counter, 10) == 0)
●
WRITE(*,*)
The following is wrong since the one-statement if a logical IF can not be another IF statement. INTEGER :: a, b, c IF (a < b) IF (b < c) WRITE(*,*)
a, b, c
From the above examples, one can easily see that if the THEN part has exactly one statement and there is no ELSE, the logical IF statement can save some space making a program a little shorter. But, my advice is that don't use it whenever it is possible.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/if.html (2 of 2)8/5/2006 8:04:44 PM
Programming Example 1: Quadratic Equation Solver
Programming Example 1: Quadratic Equation Solver Problem Statement Given a quadratic equation as follows:
if b*b-4*a*c is non-negative, the roots of the equation can be solved with the following formulae:
Write a program to read in the coefficients a, b and c, and compute and display the roots. If the discriminant b*b - 4*a*c is negative, the equation has complex root. Thus, this program should solve the equation if the discriminant is non-negative and show a message otherwise.
Solution ! --------------------------------------------------! Solve Ax^2 + Bx + C = 0 given B*B-4*A*C >= 0 ! Now, we are able to detect complex roots. ! --------------------------------------------------PROGRAM QuadraticEquation IMPLICIT NONE REAL REAL REAL !
:: a, b, c :: d :: root1, root2
read in the coefficients a, b and c READ(*,*) WRITE(*,*) WRITE(*,*) WRITE(*,*) WRITE(*,*)
a, 'a 'b 'c
b, c = ', a = ', b = ', c
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/quad-2.html (1 of 3)8/5/2006 8:04:48 PM
Programming Example 1: Quadratic Equation Solver
!
compute the square root of discriminant d d = b*b - 4.0*a*c IF (d >= 0.0) THEN ! is it solvable? d = SQRT(d) root1 = (-b + d)/(2.0*a) ! first root root2 = (-b - d)/(2.0*a) ! second root WRITE(*,*) 'Roots are ', root1, ' and ', root2 ELSE ! complex roots WRITE(*,*) 'There is no real roots!' WRITE(*,*) 'Discriminant = ', d END IF
END PROGRAM
QuadraticEquation
Click here to download this program.
Program Input and Output ●
If the input to the program consists of 1.0, 5.0 and 2.0, we have the following output. Since the discriminant is b*b 4.0*a*c = 5.0*5.0 - 4.0*1.0*2.0 = 17.0 > 0.0, the THEN part is executed and the real roots are -0.438447237 and 4.561553. 1.0
5.0
2.0
a = 1. b = 5. c = 2. Roots are -0.438447237 and -4.561553 ●
If the input to the program consists of 1.0, 2.0 and 5.0, we have the following output. Since the discriminant is b*b 4.0*a*c = 2.0*2.0 - 4.0*1.0*5.0 = -16.0 < 0.0, the ELSE part is executed and a message of no real roots is displayed followed the value of the discriminant. 1.0
2.0
5.0
a = 1. b = 2. c = 5. There is no real roots! Discriminant = -16.
Discussion Here is the box trick of this program. Note that information in different parts of the box do not have to be very precise. As http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/quad-2.html (2 of 3)8/5/2006 8:04:48 PM
Programming Example 1: Quadratic Equation Solver
long as it can tell what to do, it would be sufficient.
b*b - 4.0*a*c >= 0.0
computes the real roots there is no real roots
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/quad-2.html (3 of 3)8/5/2006 8:04:48 PM
Programming Example 2: Final Mark Computation
Programming Example 2: Final Mark Computation Problem Statement Two examination papers are written at the end of the course. The final mark is either the average of the two papers, or the average of the two papers and the class record mark (all weighted equally), whichever is the higher. The program should reads in the class record mark and the marks of the papers, computes the average, and shows PASS (>= 50%) or FAIL (< 50%).
Solution ! ! ! ! ! ! ! ! !
------------------------------------------------------------Two examination papers are written at the end of the course. The final mark is either the average of the two papers, or the average of the two papers and the class record mark (all weighted equally), whichever is the higher. The program should reads in the class record mark and the marks of the papers, computes the average, and shows PASS (>= 50%) or FAIL (< 50%). -------------------------------------------------------------
PROGRAM FinalMark IMPLICIT NONE REAL REAL REAL
:: Mark1, Mark2 :: Final :: ClassRecordMark
! the marks of the papers ! the final marks ! the class record mark
REAL, PARAMETER :: PassLevel = 50.0 READ(*,*)
! the pass level
ClassRecordMark, Mark1, Mark2
Final = (Mark1 + Mark2) / 2.0 IF (Final = PassLevel) THEN WRITE(*,*) 'Pass Status
: PASS'
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/mark.html (1 of 2)8/5/2006 8:04:49 PM
Programming Example 2: Final Mark Computation
ELSE WRITE(*,*) END IF END PROGRAM
'Pass Status
: FAIL'
FinalMark
Click here to download this program.
Program Input and Output ●
If the input to class record mark, the mark of the first paper, and the mark of the second paper are 40.0, 60.0 and 43.0, the average is (60.0 + 43.0)/2 = 51.5, which is larger than the class record mark (40.0). Therefore, this student has a final mark 51.5 and receives a PASS status. 40.0
60.0
43.0
Class Record Mark : 40. Mark 1 : 60. Mark 2 : 43. Final Mark : 51.5 Pass Status : PASS ●
If the input to class record mark, the mark of the first paper, and the mark of the second paper are 60.0, 45.0 and 43.0, then the average is (45.0 + 43.0)/2 = 44.0, which is less than the class record mark (60.0). Therefore, this student's new mark is the average of his marks and the class record mark, (60.0 + 45.0 + 43.0)/3.0 = 49.33333. Since this new mark is less than 50.0, this student receives a FAIL status. 60.0
45.0
43.0
Class Record Mark : 60. Mark 1 : 45. Mark 2 : 43. Final Mark : 49.3333321 Pass Status : FAIL
Discussion ● ● ●
● ●
The READ statement reads in values for ClassRecordMark, Mark1 and Mark2. The average of papers is computed and stored in Final If this final mark is less than or equal to the class record mark, a new final mark is computed as the average of the two marks and the class record mark. Here, the IF-THEN-END form is used. You can use the logical IF form; but, this line could be too long. As mentioned earlier, the IF-THEN-END IF is preferred. The four WRITE(*,*) statements display the input and the computed final mark. Finally, the IF-THEN-ELSE-END IF determines if the final mark is a pass or a fail.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/mark.html (2 of 2)8/5/2006 8:04:49 PM
Programming Example 3: Heron's Formula for Computing Triangle Area
Programming Example 3: Heron's Formula for Computing Triangle Area Problem Statement Given a triangle with side lengths a, b and c, its area can be computed using the Heron's formula:
where s is the half of the perimeter length:
Write a program to read in the coefficients a, b and c, and compute the area of the triangle. However, not any three numbers can make a triangle. There are two conditions. First, all side lengths must be positive:
and second the sum of any two side lengths must be greater than the third side length:
In the program, these two conditions must be checked before computing the triangle area; otherwise, square root computation will be in trouble.
Solution ! -----------------------------------------------------! Compute the area of a triangle using Heron's formula ! -----------------------------------------------------PROGRAM HeronFormula IMPLICIT NONE REAL REAL REAL
:: a, b, c :: s :: Area
! three sides ! half of perimeter ! triangle area
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/heron.html (1 of 3)8/5/2006 8:04:54 PM
Programming Example 3: Heron's Formula for Computing Triangle Area
LOGICAL
:: Cond_1, Cond_2
READ(*,*)
! two logical conditions
WRITE(*,*) WRITE(*,*) WRITE(*,*) WRITE(*,*)
a, b, c "a = ", a "b = ", b "c = ", c
Cond_1 = (a > 0.) .AND. (b > 0.) .AND. (c > 0.0) Cond_2 = (a+b > c) .AND. (a+c > b) .AND. (b+c > a) IF (Cond_1 .AND. Cond_2) THEN s = (a + b + c) / 2.0 Area = SQRT(s*(s-a)*(s-b)*(s-c)) WRITE(*,*) "Triangle area = ", Area ELSE WRITE(*,*) "ERROR: this is not a triangle!" END IF END PROGRAM
HeronFormula
Click here to download this program.
Program Input and Output ●
If the input to the program consists of 3.0, 5.0 and 7.0, we have the following output. Since the value of all input are positive and the sum of any two is larger than the third (i.e., 3.0+5.0 > 7.0, 3.0+7.0+5.0 and 5.0+7.0>3.0), both conditions hold and the program can compute the area of the triangle. The area is 6.49519062. 3.0
5.0
7.0
a = 3. b = 5. c = 7. Triangle area = 6.49519062 ●
If the input to the program consists of 3.0, 4.0 and 7.0, we have the following output. Although all input values are positive, this is not a triangle since the sum of the first side (3.0) and the second (4.0) is not grater than the third (8.0). The program generates an error message. 3.0
4.0
8.0
a = 3. b = 4. c = 8. ERROR: this is not a triangle!
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/heron.html (2 of 3)8/5/2006 8:04:54 PM
Programming Example 3: Heron's Formula for Computing Triangle Area ●
If the input to the program consists of -1.0, 3.0 and 5.0, we have the following output. Since not all input values are positive, this is not a triangle. -1.0
3.0
5.0
a = -1. b = 3. c = 5. ERROR: this is not a triangle!
Discussion ● ● ● ●
●
●
● ●
This program uses two LOGICAL variables, Cond_1 and Cond_2 to store the results of the two conditions. The conditions are checked with the first two assignments. Since all side lengths must be greater than zero, operator .AND. are used to connect a > 0.0, b > 0.0 and c > 0.0. Since the sum of any two side lengths must be greater than the third side length, all three comparisons must be . TRUE. and operator .AND. is used. Since both conditions must be true in order to have a triangle, .AND. is also used in the IF-THEN-ELSE-END IF statement. If both conditions are .TRUE., the THEN part is executed, where the value of s and the area is computed and displayed. If one or both conditions is .FALSE., the input is not a triangle and an error message is displayed. You can pull all six comparisons into a single logical expression. But, this expression could be too long to be fit into a single line. While continuation line can be used, it may not be readable. So, I prefer to have separate lines.
Here is the box trick of this program.
a, b and c form a triangle
computes s and its area displays an error message
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/heron.html (3 of 3)8/5/2006 8:04:54 PM
Nested IF-THEN-ELSE-END IF
Nested IF-THEN-ELSE-END IF The THEN part and the ELSE part, if any, can contain one or more IF-THEN-ELSE-END IF statement in one of the three forms. That is, when you feel it is necessary, you can use as many IF-THEN-ELSE-END IF statements in the THEN part and the ELSE part as you want. However, please note that any such IF-THEN-ELSE-END IF must be fully contained in the THEN part or the ELSE part. If you follow the box trick, this requirement is automatically satisfied. The following is an example: IF (logical-expression) THEN statements IF (logical-expression) THEN statements ELSE statements END IF statements ELSE statements IF (logical-expression) THEN statements END IF statements END IF
Examples ●
Suppose we need a program segment to read a number x and display its sign. More precisely, if x is positive, a + is displayed; if x is negative, a - is displayed; otherwise, a 0 is displayed. With an IF-THEN-ELSE-END IF statement, we have a two-way decision (i.e., true or false). What we need is a tree-way decision and some trick is required. In this case, the box trick can be very helpful. Let us start testing if x is positive. What we get is the following: display + x> 0 one down (i.e., +) two to go (i.e., - and 0) In the lower part, no decision can been reached. What we want to know is finding out is x is zero or negative (x cannot be positive here since it has been ruled out in the upper part). To determine whether a - or a 0 should be displayed, one more decision is required:
x<
display -
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/nest-if.html (1 of 4)8/5/2006 8:04:58 PM
Nested IF-THEN-ELSE-END IF
0
display 0)
Since this is the work for the lower rectangle, let us put it there yielding the following: display + x> 0
x< 0
display display 0
Converting to a IF-THEN-ELSE-END IF construct is easy since the above box is almost identical to that. So, here is our answer: IF (x > 0) THEN WRITE(*,*) '+' ELSE IF (x < 0) THEN WRITE(*,*) '-' ELSE WRITE(*,*) '0' END IF END IF ●
Given a x, we want to display the value of -x if x < 0, the value of x*x if x is in the range of 0 and 1 inclusive, and the value of 2*x if x is greater than 1. Obviously, this problem cannot be solved with a two-way IF and the box trick becomes useful. Let us start with x= 0
For the x >= 0 part, x may be in the range of 0 and 1; if not, x must be greater than 1 since x cannot be less than 0. Therefore, we have the following box for the case of x >= 0: x 1. display 2*x
Inserting this box into the previous one yields the following final result: display -x x< 0
x = 0 ! Now, we are able to detect complex roots and
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/quad-3.html (3 of 4)8/5/2006 8:05:03 PM
Quadratic Equation Solver - Again
! repeated roots. ! --------------------------------------------------PROGRAM QuadraticEquation IMPLICIT NONE REAL REAL REAL !
:: a, b, c :: d :: root1, root2
read in the coefficients a, b and c READ(*,*) WRITE(*,*) WRITE(*,*) WRITE(*,*) WRITE(*,*)
!
a, 'a 'b 'c
b, c = ', a = ', b = ', c
compute the discriminant d d = b*b - 4.0*a*c IF (d > 0.0) THEN ! distinct roots? d = SQRT(d) root1 = (-b + d)/(2.0*a) ! first root root2 = (-b - d)/(2.0*a) ! second root WRITE(*,*) 'Roots are ', root1, ' and ', root2 ELSE IF (d == 0.0) THEN ! repeated roots? WRITE(*,*) 'The repeated root is ', -b/(2.0*a) ELSE ! complex roots WRITE(*,*) 'There is no real roots!' WRITE(*,*) 'Discriminant = ', d END IF
END PROGRAM
QuadraticEquation
Click here to download this program. Its logic is shown below using the box trick. > computes the real roots b*b - 4.0*a*c ? 0.0
=
computes the repeated root
> no real root
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/quad-3.html (4 of 4)8/5/2006 8:05:03 PM
Quadratic Equation Solver - Revisited
Quadratic Equation Solver - Revisited Problem Statement Given a quadratic equation as follows:
if b*b-4*a*c is non-negative, the roots of the equation can be solved with the following formulae:
Write a program to read in the coefficients a, b and c, and solve the equation. Note that a quadratic equation has repeated root if b*b-4.0*a*c is equal to zero. However, if a is zero, the equation becomes a linear one whose only solution is -c/b if b is not zero. Otherwise, if b is zero, two cases are possible. First, if c is also zero, any number can be a solution because all three coefficients are zero. Otherwise, the equation c = 0 cannot have any solution. This program should handle all cases.
Solution ! --------------------------------------------------! Solve Ax^2 + Bx + C = 0 given B*B-4*A*C >= 0 ! Now, we are able to detect the following: ! (1) unsolvable equation ! (2) linear equation ! (3) quadratic equation ! (a) distinct real roots ! (b) repeated root ! (c) no real roots ! --------------------------------------------------PROGRAM QuadraticEquation IMPLICIT NONE REAL
:: a, b, c
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/quad-5.html (1 of 4)8/5/2006 8:05:07 PM
Quadratic Equation Solver - Revisited
REAL REAL !
:: d :: root1, root2
read in the coefficients a, b and c READ(*,*) WRITE(*,*) WRITE(*,*) WRITE(*,*) WRITE(*,*)
a, 'a 'b 'c
b, c = ', a = ', b = ', c
IF (a == 0.0) THEN ! could be a linear equation IF (b == 0.0) THEN ! the input becomes c = 0 IF (c == 0.0) THEN ! all numbers are roots WRITE(*,*) 'All numbers are roots' ELSE ! unsolvable WRITE(*,*) 'Unsolvable equation' END IF ELSE ! linear equation WRITE(*,*) 'This is linear equation, root = ', -c/b END IF ELSE ! ok, we have a quadratic equation d = b*b - 4.0*a*c IF (d > 0.0) THEN ! distinct roots? d = SQRT(d) root1 = (-b + d)/(2.0*a) ! first root root2 = (-b - d)/(2.0*a) ! second root WRITE(*,*) 'Roots are ', root1, ' and ', root2 ELSE IF (d == 0.0) THEN ! repeated roots? WRITE(*,*) 'The repeated root is ', -b/(2.0*a) ELSE ! complex roots WRITE(*,*) 'There is no real roots!' WRITE(*,*) 'Discriminant = ', d END IF END IF END PROGRAM
QuadraticEquation
Click here to download this program.
Program Input and Output Since we have been doing the quadratic part in several similar examples, the following concentrates on the order part of the program. ●
If the input to the program consists of 0.0, 1.0 and 5.0, we have the following output. Since a is zero, this could be a linear equation. Since b=1.0, it is a linear equation 1.0*x + 5.0 = 0.0 with the only root -5.0/2.0=-5.0. 0.0
1.0
5.0
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/quad-5.html (2 of 4)8/5/2006 8:05:07 PM
Quadratic Equation Solver - Revisited
a = 0.E+0 b = 1. c = 5. This is linear equation, root = -5. ●
If the input to the program consists of 0.0, 0.0 and 0.0, we have the following output. Since all coefficients are zero, any number is a root. 0.0
0.0
0.0
a = 0.E+0 b = 0.E+0 c = 0.E+0 All numbers are roots ●
If the input to the program consists of 0.0, 0.0 and 4.0, we have the following output. Since the equation becomes 4.0 = 0.0, which is impossible. Therefore, this is not a solvable equation. 0.0
0.0
4.0
a = 0.E+0 b = 0.E+0 c = 4. Unsolvable equation
Discussion Here is the box trick of this program. It is more complex than all previous versions of quadratic equation solvers. Let us start with linear equations.
a= 0
it could be a linear equation a quadratic equation
Since we have learned to do the quadratic part, we shall do the linear equation part first. To be a linear equation, b cannot be zero and this has to be addressed in the upper rectangle:
a= 0
b= 0
need to know if c is zero the equation is linear b*x +c=0
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/quad-5.html (3 of 4)8/5/2006 8:05:07 PM
Quadratic Equation Solver - Revisited
a quadratic equation If c is zero, then every number is a root and we have:
a= 0
b= 0
c= 0
every number is a root this equation is not solvable
the equation is linear b*x+c=0 a quadratic equation
To complete the bottom rectangle, let us take the box from previous example. The final result is:
b=0 a= 0
c= 0
every number is a root this equation is not solvable
the equation is linear b*x+c=0 b*b - 4.0*a*c ? 0.0
>
computes the real roots
=
computes the repeated root
>
no real root
The above program is written based on this logic.
http://www.cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap03/quad-5.html (4 of 4)8/5/2006 8:05:07 PM
Sort Three Numbers
Sort Three Numbers Problem Statement Give three integers, display them in ascending order. For example, if the input is 2, 3 and 1, this program should display 1, 2 and 3.
Solution ! ! ! !
------------------------------------------------------This program reads in three INTEGERs and displays them in ascending order. -------------------------------------------------------
PROGRAM Order IMPLICIT NONE INTEGER READ(*,*)
:: a, b, c a, b, c
IF (a < b) THEN IF (a < c) THEN IF (b < c) THEN WRITE(*,*) a, b, ELSE WRITE(*,*) a, c, END IF ELSE WRITE(*,*) c, a, b END IF ELSE IF (b < c) THEN IF (a < c) THEN WRITE(*,*) b, a, ELSE WRITE(*,*) b, c, END IF ELSE WRITE(*,*) c, b, a END IF END IF END PROGRAM
! a < b here ! a < c ! b < c
: a the smallest : a < b < c
c !
c