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
Type | Operator | Associativity | |||||
Arithmetic | ** | right to left | |||||
* | / | left to right | |||||
+ | - | left to right | |||||
Relational | < | <= | > | >= | == | /= | none |
Logical | .NOT. | right to left | |||||
.AND. | left to right | ||||||
.OR. | left to right | ||||||
.EQV. | .NEQV. | left to right |
.NOT. | Operand | Result |
.TRUE. | .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.).
.AND. | .TRUE. | .FALSE |
.TRUE. | .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.
.OR. | .TRUE. | .FALSE |
.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.
.EQV. | .TRUE. | .FALSE |
.TRUE. | .TRUE. | .FALSE. |
.FALSE. | .FALSE. | .TRUE. |
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.
.NEQV. | .TRUE. | .FALSE |
.TRUE. | .FALSE. | .TRUE. |
.FALSE. | .TRUE. | .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.
Here are some examples:
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. --> .FALSE. .AND. .FALSE. --> .FALSE.
.NOT. (Something .AND. Another) --> .NOT. (.TRUE. .AND. .FALSE.) --> .NOT. ([.TRUE. .AND. .FALSE.]) --> .NOT. .FALSE. --> .TRUE.
.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.
Note that the above expression, if you like, can be rewritten with parentheses as follows:n**2 + 1 > 10 .AND. .NOT. n < 3 --> 4**2 + 1 > 10 .AND. .NOT. 4 < 3 --> [4**2] + 1 > 10 .AND. .NOT. 4 < 3 --> 16 + 1 > 10 .AND. .NOT. 4 < 3 --> [16 + 1] > 10 .AND. .NOT. 4 < 3 --> 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.
(n**2 + 1 > 10) .AND. .NOT. (n < 3)
.NOT. (m > n .AND. x < y) .NEQV. (m <= n .AND. x >= y) --> .NOT. (3 > 5 .AND. 4 < 2) .NEQV. (3 <= 5 .AND. 4 >= 2) --> .NOT. ([3 > 5] .AND. 4 < 2) .NEQV. (3 <= 5 .AND. 4 >= 2) --> .NOT. (.FALSE. .AND. 4 < 2) .NEQV. (3 <= 5 .AND. 4 >= 2) --> .NOT. (.FALSE. .AND. [4 < 2]) .NEQV. (3 <= 5 .AND. 4 >= 2) --> .NOT. (.FALSE. .AND. .FALSE.) .NEQV. (3 <= 5 .AND. 4 >= 2) --> .NOT. ([.FALSE. .AND. .FALSE.]) .NEQV. (3 <= 5 .AND. 4 >= 2) --> .NOT. (.FALSE.) .NEQV. (3 <= 5 .AND. 4 >= 2) --> [.NOT. .FALSE.] .NEQV. (3 <= 5 .AND. 4 >= 2) --> .TRUE. .NEQV. (3 <= 5 .AND. 4 >= 2) --> .TRUE. .NEQV. ([3 <= 5] .AND. 4 >= 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.
Thus, Result1, Result2, Result3 and Results receive .FALSE., .FALSE., .TRUE. and .FALSE., respectively.LOGICAL :: Result1, Result2, Result3, Result4 Result1 = .NOT. Something .AND. Another Result2 = .NOT. a .OR. .NOT. b .AND. c Result3 = (n**2 + 1 > 10) .AND. .NOT. (n < 3) Result4 = .NOT. (m > n .AND. x < y) .NEQV. (m <= n .AND. x >= y)