In Chapter 2, you had seen precedence rules for arithmetic operations. Th ese rules deter-mine the priority and associativity of operators. Since an expression may involve arithmetic, relational, and logical operators, we need a precedence rule for all those operators. As men-tioned in Chapter 2, it is customary to state these rules in the form of a table (see Table 4.9).
For a complete list see Appendix A.
Table 4.9 may be quite overwhelming for anyone, particularly for a beginner. With prac-tice, you will get better at it. However, the following observations may be helpful.
1. Assignment operator has the lowest precedence. Th erefore, there is no need to enclose the expression on the right-hand side with a pair of parentheses.
In other words,
variable = (expression);
is equivalent to
variable = expression;
2. Binary logical operator has lower precedence than all arithmetic and relational oper-ators. Th erefore, there is no need to put parentheses around the operands of a binary logical operator.
Th us,
(expressionOne) && (expressionTwo) (expressionOne) || (expressionTwo)
Apago PDF Enhancer
are equivalent, respectively, to
(expressionOne && expressionTwo) (expressionOne || expressionTwo)
3. Relational operators have lower precedence than all arithmetic operators. Th erefore, there is no need to put parentheses around arithmetic expressions.
In other words,
(exp1 / exp2) <= (exp3 – exp4) are equivalent to
(exp1 / exp2 <= exp3 – exp4) TABLE 4.9 Precedence Rules
Operator Operand Types Operation Level Group Associativity
++ Numeric variable Postincrement 1 Post LR
— — Postdecrement
++ Numeric variable Preincrement 2 Pre RL
— — Predecrement
+ Number Unary plus 2 Unary
— Unary minus
! Logical Logical not
* Number, number Multiplication 4 Arithmetic LR
/ Division
% Modulus
+ Number, number Addition 5
— Subtraction
< Number, number Less than 7 Relational
<= Less than or equal
> Greater than
>= Greater than or equal
== Any type, the same type Equality operators 8
!=
^ Boolean, boolean Logical XOR 10 Logical
&& Boolean, boolean Logical AND 12
|| Boolean, boolean Logical OR 13
= Variable, same type Assignment 15 Assignment RL
*= Variable, number Assignment with operator /=
%= Variable, integer += Variable, number
−=
Apago PDF Enhancer
double valueOne = 2.25, valueTwo = 0.452;
Evaluation of Logical Expressions
Expression Value Explanation
!errorFound true !errorFound = !false =
true.
!workCompleted false !workCompleted = !true =
false.
workCompleted && !errorFound true Order of evaluation: !, &&.
true && true = true.
letter == 'P' false letter is 'J'.
workCompleted || letter == 'P' true Order of evaluation: ==, ||.
workCompleted is true;
letter == 'P' is false;
true || false = true.
!workCompleted && letter ! = 'P' false Order of evaluation: !, !=, &&.
!workCompleted is false;
letter != 'P' is true;
false && true = false.
numOne + numTwo < 15 false Order of evaluation: +, <.
numOne + numTwo is 7 + 9 = 16.
Th erefore, 16 > 15 evaluates to false.
numOne >= 0 && numOne <= 9 true Order of evaluation: >=, <=, &&.
numOne = 7. Note that 7 >= 0 and 7 >= 9 evaluate to true. true &&
true = true.
letter >= 'a' && letter <= 'z' false Order of evaluation: >=, <=, &&
letter is 'J'. Note that 'J' >=
'a' is false and 'J' <= 'z' is true. false && true = false.
letter >= 'A' && letter <= 'Z' true Order of evaluation: >=, <=, &&
letter is 'J'. Th us, 'J' >= 'A' is true and 'J' <= 'Z' is true.
true && true = true.
letter >= 'a' && letter <= 'z'
||
false Order of evaluation: >=, <=, &&, ||
letter >= 'A' && letter <= 'Z' false || true = true.
valueTwo > 0.25 && valueTwo <
0.45
false Order of evaluation: >, <, &&
valueTwo is 0.452. Th us, 0.452 >
0.25 is true. Also, 0.452 < 0.45 is false. true && false = false.
(continued )
Apago PDF Enhancer
Expression Value Explanation
valueOne < 7.75 true valueOne is 2.25. Th us, 2.25 <
7.75 is true valueOne < 7.75 || valueTwo >
2.5 && valueTwo < 10
false true || false = true.
(valueOne < 7.75 || valueTwo >
2.5)&& valueTwo < 10
true (true || true) && false = true && false = false.
Th e following example verifi es our computations through a Java program.
Example 4.9 /**
Illustrates the operator precedence involving logical operators
*/
public class OperatorPrecedence {
public static void main(String[] args) {
System.out.println("!workCompleted is "
+ (!workCompleted));
System.out.println("workCompleted && !errorFound is "
+ (workCompleted && !errorFound));
System.out.println("letter == 'P' is "
+ (letter == 'P'));
System.out.println("workCompleted || letter == 'P' is "
+ (workCompleted || letter == 'P'));
System.out.println("!workCompleted && letter != 'P' is "
+ (!workCompleted && letter != 'P'));
System.out.println("numOne + numTwo < 15 is "
+ (numOne + numTwo < 15));
System.out.println("numOne >= 0 && numOne <= 9 is "
+ (numOne >= 0 && numOne <= 9));
System.out.println("letter >= 'a' && letter <= 'z' is "
+ (letter >= 'a' && letter <= 'z'));
Apago PDF Enhancer
System.out.println("letter >= 'A' && letter <= 'Z' is "
+ (letter >= 'A' && letter <= 'Z'));
System.out.println("letter >= 'a' && letter <= 'z' || "
+ "letter >= 'A' && letter <= 'Z' is "
+ (letter >= 'a' && letter <= 'z' ||
letter >= 'A' && letter <= 'Z' ));
System.out.println("valueTwo > 2.5 && valueTwo < 0.45 is " + (valueTwo > 2.5 && valueTwo < 0.45));
System.out.println("valueOne < 7.75 is "
+ (valueOne < 7.75));
System.out.println("valueOne < 7.75 || valueTwo >
0.25 " + "&& valueTwo < 0.45 is "
+ (valueOne < 7.75 || valueTwo > 0.25 && valueTwo < 0.45));
System.out.println("(valueOne < 7.75 || valueTwo >
0.25) "+ "&& valueTwo < 0.45) "
+ ((valueOne < 7.75 || valueTwo > 0.25)
&& valueTwo < 0.45));
} }
Output
!errorFound is true
!workCompleted is false
workCompleted && !errorFound is true letter == 'P' is false
workCompleted || letter == 'P' is true
!workCompleted && letter != 'P' is false numOne + numTwo < 15 is false
numOne >= 0 && numOne <= 9 is true letter >= 'a' && letter <= 'z' is false letter >= 'A' && letter <= 'Z' is true
letter >= 'a' && letter <= 'z' || letter >= 'A' && letter <=
'Z' is true
valueTwo > 0.25 && valueTwo < 0.45 is false valueOne < 7.75 is true
valueOne < 7.75 || valueTwo > 0.25 && valueTwo < 0.45 is true (valueOne < 7.75 || valueTwo > 0.25) && valueTwo < 0.45) false Note 4.4 Parentheses can be used to change the order of execution. In particular, consider the last two expressions in Example 4.9.
Apago PDF Enhancer
valueOne < 7.75 || valueTwo > 0.25 && valueTwo < 0.45 is true (1) (valueOne < 7.75 || valueTwo > 0.25) && valueTwo < 0.45) false (2) In expression 1 above, no parentheses were used. Th us, logical and operation is carried out before the logical or. In expression 2, due to the parenthesis, logical or is carried out before the logical and. Th us, in the case 1 the expression is evaluated to true, whereas in case 2 it is evaluated to false.
Self-Check
15. True or false: Relational operators have higher precedence than assignment operators.
16. True or false: Logical operators have higher precedence than arithmetic operators.
Advanced Topic 4.3: Syntax Error Explained
Th e logical expressions (letter >= 'a' && letter <= 'z') and ('a' <= letter &&
letter <= 'z') are equivalent. However, it cannot be written as ('a' <= letter <=
'z'). Many beginning programmers wonder why one could write (valueOne + value-Two + valueThree) without any syntax error; while ('a' <= letter <= 'z') is not legal in Java. Th e reason can be explained as follows: Th e expression (valueOne + value-Two + valueThree) is evaluated in two steps. First, valueOne + valueTwo is com-puted. Th e result of this computation is a numeric value and is added to valueThree.
However, 'a' <= letter is a logical expression. Th erefore, 'a' <= letter is either true or false. Th erefore, ('a' <= letter <= 'z') is either (true <= 'z') or (false <=
'z'). Since a relational operator cannot be used to compare a logical value with a charac-ter, ('a' <= letter <= 'z') is an illegal expression.
Advanced Topic 4.4: Short-Circuit Evaluation In the case of logical operation or, you know that true || false is true
and
true || true is true
In other words, if the fi rst operand evaluates to true, the value of the second operand has no bearing on the fi nal result. Th us, in a logical expression of the form
(logicalExpressionOne || logicalExpressionTwo)
if logicalExpressionOne evaluates to true, there is no need to evaluate logicalExpressionTwo.
Similarly, in the case of logical operation and false && false = false
Apago PDF Enhancer
and
false && true = false
Th us, if the fi rst operand evaluates to false, the value of the second operand has no bear-ing on the fi nal result. Th us, in a logical expression of the form
(logicalExpressionOne && logicalExpressionTwo)
if logicalExpressionOne evaluates to false, there is no need to evaluate logicalExpressionTwo.
Java compiler makes use of these facts and skips the evaluation of operands accordingly.
Th is method of evaluating a logical expression is called the short-circuit evaluation.
Advanced Topic 4.5: Additional Logical Operators
Java provides two other operators & and |. You can use these operators instead of && and
||, respectively, to avoid short-circuit evaluation. Some programmers use them to achieve certain side eff ects as shown in the following example. Author does not recommend their approach. Th e following example is given only to illustrate operators & and |.
Example 4.10 Consider the following declarations:
int numOne = 7, numTwo = 9, numThree = 20;
In the case of the following expression,
(numOne <= numTwo || numTwo == numThree++)
the fi rst operand of the or operator numOne <= numTwo evaluates to true.
Due to short-circuit evaluation, second operand (numTwo == numThree++) is never evaluated. Th erefore, the variable numThreeis not incremented by 1. Th us, numThreeis20. However, in the following expression,
(numOne <= numTwo | numTwo == numThree++)
no short-circuit evaluation is performed and the second operand (numTwo ==
numThree++) is evaluated. Th e variable numThree is incremented by 1. Th us, numThree becomes 21.
For a slightly more complex example, consider the following declaration and the logical expression:
int numFour = 107, numFive = 109, numSix = 120;
(numFour >= numFive && 200 <= numFive++ || 300 == numSix++)
Apago PDF Enhancer
In this case, since fi rst operand numFour >= numFiveof the logical and oper-ation is false, the second operand 200 <= numFive++ of the logical and opera-tions is never performed. Th us, we have the intermediate result
false || 300 == numSix++
Now, the fi rst operand of a logical or operation is false. Th erefore, no short-circuit evaluation is possible. Recall that in the case of a logical or operation, com-piler will employ short-circuit evaluation only if the fi rst operand is true. Th us, in this case, compiler evaluates the operand 300 == numSix++. Th erefore, aft er evaluating the statement
(numFour >= numFive && 200 <= numFive++ || 300 == numSix++) the variable numFive is not incremented by 1 while the variable numSix is incre-mented by 1.
However, the following expression evaluates every operand, and thus as a side eff ect increments both variables numFive and numSix:
(numFour >= numFive & 200 <= numFive++ | 300 == numSix++) In this book we will consistently use expressions with no side eff ects. Th erefore, we will not be using logical operators & and |.
Example 4.11
Th is example provides a Java program to verify Example 4.10.
/**
Operator precedence involving logical operators
*/
public class ShortCircuitEvaluation {
public static void main(String[] args) {
int numOne = 7, numTwo = 9, numThree = 20;
int numFour = 107, numFive = 109, numSix = 120;
System.out.println("(numOne <= numTwo ||"
+ " numTwo == numThree++) is "
+ (numOne <= numTwo || numTwo == numThree++));
System.out.println("numThree is " + numThree);
System.out.println("(numOne <= numTwo |"
+ " numTwo == numThree++) is "
+ (numOne <= numTwo | numTwo == numThree++));
Apago PDF Enhancer
System.out.println("numThree is " + numThree);
System.out.println("(numFour >= numFive &&"
+ " 200 <= numFive++ || 300 == numSix++) is "
+ (numFour >= numFive && 200 <= numFive++
|| 300 == numSix++));
System.out.println("numFive is " + numFive);
System.out.println("numSix is " + numSix);
System.out.println("(numFour >= numFive &"
+ " 200 <= numFive++ | 300 == numSix++) is "
+ (numFour >= numFive & 200 <= numFive++
| 300 == numSix++));
System.out.println("numFive is " + numFive);
System.out.println("numSix is " + numSix);
} }
Output
(numOne <= numTwo || numTwo == numThree++) is true numThree is 20
(numOne <= numTwo | numTwo == numThree++) is true numThree is 21
(numFour >= numFive && 200 <= numFive++ || 300 == numSix++) is false
numFive is 109 numSix is 121
(numFour >= numFive & 200 <= numFive++ | 300 == numSix++) is false
numFive is 110 numSix is 122
Advanced Topic 4.6: Positive Logic
Research studies have shown that it is easy to understand positive logic compared to nega-tive logic. In this section, we discuss De Morgan’s rule and other techniques for converting a negative logic expression into a positive one.
Consider the following expression:
!(numOne > 7).
Th is is an example of negative logic. To convert this logical expression into a positive logic, replace the relational operator > with its complement relational operator <=. Th us, the logical expression !(numOne > 7) can be replaced by the following equivalent logical expression:
(numOne <= 7)
Apago PDF Enhancer
Table 4.10 shows each relational operator and its complement operator.
Now let us consider a more complex expression involving logical operators && and ||.
In this case, you can apply De Morgan’s rules as follows:
!(expOne && expTwo) is equivalent to !(expOne) || !(expTwo) and
!(expOne || expTwo) is equivalent to !(expOne) && !(expTwo) Example 4.12
Expression Modifi ed Expression and Explanation
!(numOne < 17 || NumTwo > 9) = !(numOne < 17) && !(NumTwo > 9)
= (numOne >= 17) && (NumTwo <= 9)
= (numOne >= 17 && NumTwo <= 9).
!(numOne <= 17 && NumTwo > 9) = !(numOne <= 17) || !(NumTwo > 9)
= (numOne > 17) || (NumTwo <= 9)
= (numOne > 17 || NumTwo <= 9).
!(numOne <= 17 && NumTwo > 9 = !((numOne <= 17 && NumTwo > 9) ||
|| letter == 'P') (letter == 'P'))
= !(numOne <= 17 && NumTwo > 9) &&
!(letter == 'P')
= !(numOne >= 17) && !(NumTwo < 9 &&
letter != 'P') TABLE 4.10 Th e Complement of a Relational Operator
Operator Complement Negative Expression Positive Expression
< >= !(numOne < 7) (numOne >= 7)
Apago PDF Enhancer
Expression Modifi ed Expression and Explanation
= !(numOne >= 17) && (!(NumTwo < 9) ||!(letter != 'P'))
= !(numOne > 17) && !(NumTwo <= 9) &&
!(!workCompleted)
= (numOne <= 17) && (NumTwo > 9) &&
(workCompleted)
= (numOne <= 17 && NumTwo > 9 &&
workCompleted).
!(numOne > 17 && NumTwo != 9
= !((numOne > 17 && NumTwo != 9) &&
&& !workCompleted) (!workCompleted))
Java provides three structures for selection and decision making. In the next section, we discuss the one-way selection structure if. Th e two-way selection structure if … else and the multiway selection structure switch are introduced later in this chapter.
Although Java provides three diff erent structures, any decision making can in fact be per-formed using a sequence of if structures. In other words, a two-way decision structure can be replaced by two one-way decision structures. Similarly, a n-way decision-making structure can in fact be replaced by n one-way decision-making structures. Th ese issues will be further explored later in this chapter.
ONE-WAY SELECTION STRUCTURE
A university may place a student in its prestigious dean’s list if the student has at least 3.75 grade point average (gpa) out of a possible 4.0. Th us, if the gpa of a student is greater than or equal to 3.75, student’s name is entered into dean’s list. However, if the gpa of a student is less than 3.75, no action needs to be carried out. Th is is a situation where a one-way selection structure is appropriate. Similarly, an automobile insurance fi rm may apply a