1 / 64

Controlling Program Flow with IF Constructs

Learn how to control the flow of your program using logical expressions and IF constructs in Fortran 90. Understand the block IF structure and how to compare character strings. Explore alternative control statements and obsolete forms.

pstamey
Download Presentation

Controlling Program Flow with IF Constructs

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter 5 Controlling the flow of your program 5.1 Choice and decision-making 5.2 Logical expressions and LOGICAL variables 5.3 The block IF construct 5.4 The logical IF statement 5.5 Comparing character strings 5.6 The CASE construct 5.7 Obsolete forms of control statements

  2. 5.1 • Program executes alternative instructions depending on conditions: • Block IF construct: • E.g. For x >= 0 : • IF(ABS(x) < 1.E-20) THEN • cube_root =0.0 • ELSE • cube_root = EXP(LOG(x)/3.0 ) • ENDIF • Note: |X| in F90 is ABS(X) • X 1/3 = elog(x)/3

  3. 5.1 Fortran 90 alternatives: IF(criterion_1) THEN action_1 ELSE IF (criterion_2) THEN action_2 ELSE IF (criterion_3) THEN action_3 ELSE action_4 END IF A minimal block IF: IF (criterion) THEN action END IF

  4. 5.2 Logical expressions and LOGICAL variables -Logical values are true or false: In FORTRAN 90: .TRUE. .FALSE. are the constants for true or false. -Logical expressions e.g. L = a > b !e.g. true for a=3, b=1 x= =y ! e.g false for x =3, y =1 Also, are called ‘relational expressions’ and ‘ > ’ , ‘= =‘ are ‘relational operators’.

  5. 5.2 (2) Relational operators and expressions: a < b and a .LT. b are true if a is less than b a <= b and a .LE. b are true if a is less than or equal to b a > b and a .GT. b are true if a is greater than b a>=b and a .GE. B are true if a is greater than or equal to b a == b and a .EQ. b are true if a is equal to b a /= b and a .NE. b are true if a is not equal to b Redundancy in using operators for log. Expression of the same condition: e.g b**2 >= 4*a*c b**2-4*a*c >= 0 !e.g.TRUE for b =5, a =2, c =3 4*a*c <= b**2 4*a*c-b**2 <= 0

  6. 5.2 (3) -Alsorel. operator’s can express relation between char. expressions: e.g: string_1 <= string_2 “Adam” <= “Eve” ! True LOGICAL var’s : LOGICAL :: var_1, var_2, var_3 e.g: var_1 = (a > b) const’s .TRUE. , .FALSE. Write functions which deliver a logical value: LOGICAL FUNCTION logical_fun (arg1, ...) . .or FUNCTION logical_fun (arg1, ...) LOGICAL :: logical_fun .

  7. 5.2 (5) Form composite logical expressions using .OR. , .AND. ‘logical operators’: e.g (a<b) .OR. (c<d) or (x<=y) .AND. (y<=z) ‘(‘ , ‘)’ can be omitted e.g a<b .OR. c<d ! But may confuse us; so use ‘(‘ , ‘)’ (a<b) .OR. (c<d) e.g. a = 2 , b = 3 , c = 5 , d = 3 => value of log. expr. = .TRUE.

  8. 5.2 (6) The logical operators .OR. and .AND. L1 L2 L1.OR.L2 L1.AND.L2 truetruetruetrue truefalsetruefalse false true truefalse falsefalsefalsefalse e.g. L1 = (a < b) !as above L2 = (c < d) !as above L1. OR .L2 = .TRUE. L1. AND .L2 = .FALSE The logical operators.EQV. and.NEQV.. L1L2L1.EQV.L2 L1.NEQV.L2 true true true false true false false true false true false true false false true false

  9. 5.2 (7) .EQV. If both expressions have the same value, else .NEQV. .=> useful to simplify structure of the expressions: The following two expressions are identical in their effect: L1 L2 L3 L4 e.g. (I)(a<b .AND. x<y) .OR. (a>=b .AND. x>=y) ex1 ex2 (II) a<b .EQV. x<y L1 L2 The explanation for this follows by writing the truth Table for each (I) and (II) and checking that the same ‘T’ , ‘F’ occur in all cases: (e.g. L1= 2<3 ; L2= 5<8 )

  10. 5.2 (7’)

  11. 5.2 (8) . NOT. is a unary operator gives .TRUE. for value .FALSE. and vice-versa e.g. The following expressions are equivalent in their effect: (I) .NOT. (a<b .AND. b<c) !e.g. a = 2 , b = 3 (II) a>=b .OR. b>=c ! c = 5 And, of course (I) .NOT. (a<b .EQV. x<y) (II) a<b .NEQV. x<y .NOT. Helps clarify expressions . (a+b) < (c+d) .Order : 1st : arithmetic operators (e.g. *, +, etc) ; 2nd: relational operators (e.g. < , = = etc); 3rd: logical operators

  12. 5.2 (9) Logical operator priorities: OperatorPriority . NOT. highest .AND. .OR. .EQV. and .NEQV. lowest

  13. 5.3 The block IF construct The block IF construct is: IF(logical_expression) THEN ELSE IF(logical_expression) THEN e.g. IF(.NOT. (a < b. AND. b < c)) X = a + b ELSE IF (a < b. AND. b < c) X = c + b ENDIF

  14. 5.3 (3) The block IF structure: IF(logical expression) THEN block of Fortran statements ELSE IF (logical expression)THEN block of Fortran statements ELSE IF (logical expression)THEN . . . ELSE block of Fortran statements END IF

  15. 5.3 (4) EXAMPLE 5.1 (1) Problem Example 4.1 calculated the number of bags of wheat that were required to sow a triangular field. 2s = a + b + c => area = (s(s-a)(s-b)(s-c))1/2 Use IF statement for no. of full bags needed to sow the field. Analysis: quantity(of wheat) = area * density => no. of bags = quantity / 10,000 + 0.9 (to allow for partly used bag). Better way use ‘IF’

  16. 5.3 (5) (2) Structure Plan 1 Read lengths of sides of field (a, b and c) 2 Calculate the area of the field 3 Read the sowing density 4 Calculate the quantity of seed required 5 Calculate number of full bags needed 6 If any more seed is needed then 6.1 Add one to number of bags 7 Print size of field and number of bags

  17. 5.3 (6) (3) Solution (p139.f) PROGRAM wheat_sowing IMPLICIT NONE ! A program to calculate the quantity of wheat required to ! sow a triangular field ! Variable declarations REAL :: a, b, c, s, area, density, quantity INTEGER :: num_bags ! Read the lengths of the sides of the field PRINT *, "Type the lengths of the three sides of the field & &in meters: " READ *, a, b, c

  18. 5.3 (7) ! Calculate the area of the field s = 0.5*(a+b+c) area = SQRT(s*(s-a)*(s-b)*(s-c)) ! Read sowing density PRINT *, "What is the sowing density (gm/sq.m.)? " READ *, density ! Calculate quantity of wheat in grams and the number of ! full 10 kg bags quantity = density*area num_bags = 0.0001*quantity !partly-full bag is excluded: (i) ! In section 4.1: num_bags =0.0001*quantity+0.9! To round up

  19. 5.3 (8) ! Check to see if another bag is required IF (quantity > 10000*num_bags) THEN  ! (ii) num_bags = num_bags+1 END IF ! Print results PRINT *, "The area of the field is ", area, " sq. meters" PRINT *, "and ", num_bags, " 10 kilo bags will be required" END PROGRAM wheat_sowing

  20. 5.3 (9) NOTE: 1. In (i), num_bags is INTEGER and quantity is REAL 2. In (ii), quantity > 10000 * num_bags is converted to REAL (quantity - 10000 * num_bags ) > 0.0 3. Accuracy of real arithmetic : recall REAL no’s are stored as approximations in the computer e.g. with 6 significant figures 25.39004 is stored as 25.3900 OR 25.39. Also in operations e.g Rounding in hand calculation(Fig5.10) : 25.39 * 17.25 = 437.9775 = 437.978 If 7-th digit = 0,..,4 truncate from 7-th digit on. If 7-th digit = 5,..,9 add 1 to 6-th digit & truncate from 7-th digit on 4. Computer rounding is similar. Recall e.g. Fig.3.3 Mantissa or fraction exponent form: 0 34 1 3 7 0 2 = .413702*103= 413.702 expfraction

  21. 5.3 (10) For no’s in Fig.5.10 : 25.39 = .253900 * 102, 17.25 = .172500* 102 and 25.39*17.25 =.4379775 * 103 =.437978 *103 5.The no. of digits in the fractions allowed(e.g in the example is: 6) is called precision. Real type has 24 bits = 7 or 8 decimal digits. ‘DOUBLE PRECISION’ type (in chapter 10) allows 14 or 15 decimal digits. 6. In REAL & INTEGER expressions INTEGER are converted to REAL e.g. (Chapter 3) a = b*c/d (b =100.0, c =9, d =10) => b*c =900.0 => 90.0 BUT a= c/d*b => (c/d =0, INTEGER division) => a =0.0 7. (a) For (i): Convert REAL to INTEGER before storing result. (b) For (ii): compare or subtract 2 real no’s which are almost equal e.g. Farm field sides: a=130,m =c, b=100m, density =25g/m2 =>area =6000m2 => 150kg seed => num_bags =15

  22. In computer possibly : area =5 999.999 999 or = 6000.000 001 =>num_bags=.0001*quantity=14.999 999 99OR 15.000 000 01 which is approx = 15 BUT if we simply truncate to get INTEGER we get 14 or 15; if We compute 10000*num_bags and e.g. quantity =150000.0001 then if (quantity-10000*num_bags)>0.0 is .TRUE. => 16 bags. To allow for (round) errors less than 10% write prog: REALMixed: (INTEGER,REAL) IF (quantity > 10000*num_bags+1000) THEN num_bags = num_bags + 1 END IF

  23. 5.3 (11) OR BETTER avoid num_bags: REAL REAL REAL IF (0.0001*quantity - INT(0.0001*quantity) > 0.1) THENnum_bags = num_bags + 1 END IF e.g. INT(150,000.0001) = 150,000

  24. 5.3 (12) EXAMPLE 5.2 (1) Problem Write an external function for X1/3 (2)Analysis We have done X1/3 = cube root = EXP(LOG(X))/3.0) for X > 0 Need (-X)1/3 = -(X)1/3 for X >0 and (0)1/3 = 0 special case because Log(X) undefined for X =0

  25. Data design PurposeTypeName A Dummy argument: Value whose cube REAL x root is required B Result variable: Cube root of x REAL cube_root C Local constant: A very small number REAL epsilon e.g. = 1E-10

  26. 5.3 (13) Structure plan  Real function cube_root(x) 1 If 1.1 Return zero else of x<0 1.2 Return –exp(log(-x)/3) else 1.3 Return exp(log(x)/3)

  27. 5.3 (14) (3) Solution (p143.f) REAL FUNCTION cube_root(x) IMPLICIT NONE ! Function to calculate the cube root of a ! real number ! Dummy argument declaration REAL, INTENT(IN) :: x ! Local constant REAL, PARAMETER :: epsilon=1.E-10

  28. 5.3 (15) ! Eliminate (nearly) zero case IF (ABS(x)<epsilon) THEN cube_root = 0.0 ! Calculate cube root by using logs ELSE IF (x<0) THEN ! First deal with negative argument cube_root = -EXP(LOG(-x)/3.0) ELSE ! Positive argument cube_root = EXP(LOG(x)/3.0) END IF END FUNCTION cube_root

  29. 5.3 (16) • EXAMPLE 5.3 • Problem • Modify the subroutine line_two_points, so that it returns • an error flag to indicate that either • (a) the two points were distinct, and the equation of • the joining line was therefore calculated, or • (b) it was not possible to calculate the line because • the points were coincident.

  30. 5.3 (17) (2) Analysis Need: logical error flag for equal points; Return STATUS =0 for distinct pts and STATUS = -1 otherwise Structure plan Subroutine line_two_points(line_1, point_1, point_2, status) TYPE(line) :: line_1 TYPE(point) :: point_1, point_2 INTEGER :: status 1 If point_1 and point_2 are coincident 1.1 Set status to –1 Else 1.2Calculate coefficients of the line joining the points 1.3Set status to 0

  31. 5.3 (18) (3) Solution (p144.f) MODULE geometric_procedures USE geometric_data IMPLICIT NONE CONTAINS SUBROUTINE line_two_points(line_1,point_1,point_2,status) IMPLICIT NONE ! Dummy arguments TYPE(Line), INTENT(OUT) :: line_1 TYPE(Point), INTENT(IN) :: point_1,point_2 INTEGER :: status

  32. 5.3 (19) ! Check whether points are equal, using ABS(). e.g. for x coord: Take ! epsilon = 1.E-10 and IF( ABS(point_1%x - point_2%x ) < epsilon IF (point_1%x==point_2%x .AND. point_1%y==point_2%y) THEN ! Points are coincident - return error flag status = -1 ELSE ! Points are distinct, so calculate the coefficients ! of the equation representing the line line_1%a = point_2%y - point_1%y line_1%b = point_1%x - point_2%x line_1%c = point_1%y*point_2%x - point_2%y*point_1%x ! Set status to indicate success status = 0 END IF END SUBROUTINE line_two_points END MODULE geometric_procedures

  33. 5.4 The logical IF statement The logical IF statement omits ‘THEN’ : IF(logical expression) Fortran statement e.g. IF(quantity > 10000*num_bags) num_bags = num_bags+1 This is exactly equivalent to a block IF with a block consisting of a single statement: IF(logical expression) THEN Fortran statement END IF

  34. 5.5 Comparing character strings The six relational operators could be used to compare character expressions and constants. e.g. “Adam” > “Eve” ! ? True The key is the collating sequence of letters, digits and other characters. Six rules: (1) The 26 upper case letters are collated in the following order: A B C D E F G H I J X L M N 0 P Q R S T U V W X Y Z (2) The 26 lower case letters are collated in the following order: a b c d e f g h i j k 1 m n o p q r s t u v w x y z (3) The 10 digits are collated in the following order: 0 1 2 3 4 5 6 7 8 9

  35. 5.5 (2) (4) Digits are either all collated before the letter A, or all after the letter Z (5) Digits are either all collated before the letter a, or all after the letter z (6) A space (or blank) is collated before both letters and digits The other 22 characters in the Fortran character set do not have any defined position in the collating sequence.

  36. 5.5 (3) • When two character operands are being compared there are • three distinct stages in the process: • If the two operands are not the same length, the shorter one • is treated as though it were extended on the right with blanks. • (2) The two operands are compared character by character, • starting with the leftmost character. • If a difference is found the character which comes earlier in • the collating sequence being deemed to be the lesser of the two. • If no difference is found, then the strings are considered to be equal.

  37. 5.5 (4) e.g. “Adam” > “Eve” !False “Adam” < “Eve” !True “Adam” < “Adamant” !True “ “ < “a” “120” < “1201” !True “ “ < “1” “ADAM” < “Adam” !Not defined : “D” “d” “ XA” < “ X4” !Not defined : “A” “4” “var_1” < “var-1” !Not defined : “_” “-” NOT a problem, because strings are compared usually (?) if they are equal e.g. “XA” = = “X4” !False

  38. 5.5 (5) FORTRAN 90 does not define whether upper case letters come before or after lower case letters. The value of s1="ADAM" < s2="Adam" will depend upon the particular computer system being used. There are intrinsic functions which use the ASCII char’s order to decide the order of strings Intrinsic functions for lexical comparison: LGT(sl, s2) is the same as sl > s2 using ASCII character ordering. LGE(sl, s2) is the same as sl >= s2 using ASCII character ordering. LLE(sl, s2) is the same as sl <= s2 using ASCII character ordering. LLT(sl, s2) is the same as sl < s2 using ASCII character ordering.

  39. 5.5 (6) If it is required to define the ordering of all characters, another way of comparing uses the ordering of characters defined in the American National Standard Code for Information Interchange referred to as ASCII.(Appendix D, p. 727) e.g. in Fortran: “Miles” > “miles” is undefined. But LGT (“Miles”,”miles”) = .FALSE. (because “M” before “m” in ASCII)

  40. 5.5 (7) • EXAMPLE 5.4 (SKIPPED, not in exams) • (1) Problem • Write a function which takes a single character as its argument • and returns a single character according to the following rules: • If the input character is a lower case letter then return its upper case equivalent. If the input character is an upper case letter then return its lower case equivalent. If the input character is not a letter then return it unchanged.

  41. 5.5 (8) (2) Analysis IACHAR provides the position of its character argument in the ASCII collating sequence ACHAR returns the character at a specified position in that sequence.   Every lower case character is exactly 32 positions after its upper case equivalent. Use intrinsic functions IACHAR(“A”) = 65 (=position in ASCII) ACHAR(97) = a. Note: position (in ASCII) of lower case letter – position (in ASCII) of upper case letter =32 e.g. IACHAR(“a”) – IACHAR(“A”) = 97-65 = 32

  42. 5.5 (9) e.g. A –> a, change_case =ACHAR(IACHAR(“A”)+32)= ACHAR(65+32) = ACHAR(97) = “a” a –> A, change_case =ACHAR(IACHAR(“a”)-32)= ACHAR(97-32) = AHAR(65) = “A” Data design: PurposeTypeName A Dummy argument: Character to be CHARACTER*1 char converted  B Result variable: Converted character CHARACTER*1 change_case  C Local constant: Offset between upper INTEGER upper_to_lower and lower case in the ASCII character set

  43. Structure plan: Character function change_case(char) 1 If A 1.1Return character upper_to_lower after char in ASCII else if a 1.2return character upper_to_lower before char in ASCII else 1.3Return char unaltered 5.5 (10)

  44. 5.5 (11) (3) Solution (p150.f) CHARACTER FUNCTION change_case(char) IMPLICIT NONE ! This function changes the case of its argument (if it ! is alphabetic) ! Dummy argument CHARACTER, INTENT(IN) :: char ! Local constant INTEGER, PARAMETER :: upper_to_lower = IACHAR("a")-IACHAR("A") ! Check if argument is lower case alphabetic, upper case ! alphabetic, or non-alphabetic

  45. 5.5 (12) IF ("A"<=char .AND. char<="Z") THEN ! Upper case - convert to lower case change_case = ACHAR(IACHAR(char)+upper_to_lower) ELSE IF ("a"<=char .AND. char<="z") THEN ! Lower case - convert to upper case change_case = ACHAR(IACHAR(char)-upper_to_lower) ELSE ! Not alphabetic change_case = char END IF END FUNCTION change_case

  46. 5.6 The CASE construct The CASE construct deal with many alternatives are mutually exclusive. The CASE structure: SELECT CASE (case expression) CASE (case selector) !mutually exclusive case block of Fortran statements CASE (case selector)!mutually exclusive case block of Fortran statements   . . END SELECT Note: expression is integer, char, logical. But ‘real’ expressions are not allowed.

  47. 5.6 (2) e.g. CHARACTER(LEN=2):: month and assume we want to consider the first 6 no’s and the last 6 no’s: SELECTCASE(month) CASE(“01”, “02”, “03”, “04”, “05”, “06”) -statement CASE(“07”, “08”, “09”, “10”, “11”, “12”) -statement END SELECT

  48. 5.6 (5) EXAMPLE 5.5 (1)Problem Date : yyyy –mm –dd Prog. input : date Output : what season it is in Australia (2) Analysis Data design: PurposeTypeName Date (yyyy-mm-dd) CHARACTER*10 date Month (for CASE) CHARACTER*2 month

  49. 5.6 (7) Structure plan: 1 Read date 2 Extract month from date 3 Select case on month 3.1month is 8, 9 or 10 Print “spring” 3.2month is 11, 12, 1, 2 or 3 Print “summer” 3.3month is 4 or 5 Print “autumn” 3.4month is 6 or 7 Print “winter” 3.5month is anything else Print an error message

  50. 5.6 (8) (3) Solution (p155.f) PROGRAM seasons IMPLICIT NONE ! A program to calculate in which season a specified date lies ! Variable declarations CHARACTER(LEN=10) :: date CHARACTER(LEN=2) :: month ! Read date PRINT *, "Please type a date in the form yyyy-mm-dd" READ *, date ! Extract month number month = date(6:7) !2006-09-21

More Related