Suppose you saw the following statement in a program:
Num = 2 + 3 * 5
What does Num equal? Does Num equal 25 or 17 ? In other words, is the expression resolved as this:
Num = 2 + 3 * 5 Num = 5 * 5 Num = 25
or is the expression resolved as this:
Num = 2 + 3 * 5 Num = 2 + 15 Num = 17
As it turns out, Num is equal to 17 . The reason is because of the concept of operator precedence, which determines the order in which complex expressions are resolved. This statement:
Num = 2 + 3 * 5
has two binary arithmetic operators (that is, + and * ) and one assignment operator. Clearly, the arithmetic operations must be resolved before the assignment can occur. Operator precedence determines the order in which the arithmetic operations are performed. Table 9.3 presents the precedence order for the arithmetic operators, starting with the highest operator precedence (exponentiation) and proceeding to the lowest operator precedence (addition and subtraction).
Table 9.3. Arithmetic Operator Precedence
Using Table 9.3, you can see that in this statement:
Num = 2 + 3 * 5
the multiplication operator ( * ) and its operands ( 3 and 5 ) are resolved first ( 15 = 3 * 5 ) because multiplication has higher precedence that does addition. Therefore, the operands for the addition operator are 2 and 15 , causing a result of 17 to be assigned into Num .
As you can see in Table 9.3, several arithmetic operators have equal precedence. The unary operators share the same precedence level, as do multiplication and division and addition and subtraction. When these operators are used in a single statement, how does Visual Basic .NET decide which expression to resolve first?
The rules of associativity determine the order of resolution for expressions that have operators of equal precedence. All binary operators are left associative. This means the operators are resolved in a left-to-right order. For example, in this statement:
Num = 5 * 4 / 2
the expressions are resolved in the following manner:
Num = 5 * 4 / 2 Num = 20 / 2 Num = 10
Notice that the expression for multiplication is done first, followed by division. Visual Basic .NET simply starts with the leftmost expression; it resolves that expression, and the result becomes the operand for the remaining binary expression.
It is important that you recognize that this statement:
Num = 5 * 4 / 2
contains three subexpressions . The three binary expressions are resolved according to the rules of associativity. The associativity rules cause the resolution to be multiplication, then division, then assignment. You could rewrite the statement to illustrate this order of resolution:
Num = 5 * 4 / 2
which you can reduce to this:
Num = operand1 * operand2 / operand3 Num = ResultantOperand1 / operand3 Num = Result
Notice how this:
operand1 * operand2
forms a binary expression for the multiplication operation. If you plug in these numbers :
operand1 * operand2 5 * 4
You see that the value 20 becomes ResultantOperand1 in the second expression:
Num = ResultantOperand1 / operand3 Num = 20 / 2
After this binary expression is resolved, the assignment expression becomes this:
Num = 10
This causes the rvalue of Num to assume the value 10 .
You might be saying, "Wait a minute. If the operators group left to right, why isn't the assignment expression resolved first?" It's because the binary assignment operator has the second-lowest precedence of all operators. (The comma is last.) Therefore, the arithmetic expressions are resolved before the assignment expression is processed .
Altering Precedence Order
At times you might need to have an expression execute in a specific order, even if it disagrees with the precedence rules. For example, suppose you have a business that sells items after a 20% markup. Further assume that the sales tax rate for your state is 5%. Therefore, the cost to the customer is the cost of the item plus the 20% markup plus the 5% sales tax on the marked -up item price. Therefore, the sales equation is this:
CustomerPrice = Cost + Markup * SalesTax
You might write this equation in Visual Basic .NET as follows :
CustomerPrice = Cost + .2 * Cost * 1.05
You need to multiply by 1.05 because the final price to the customer is 105%, after tax is added. If you resolve this equation, assuming that the item costs $100, you get this:
CustomerPrice = Cost + .2 * Cost * 1.05 CustomerPrice = 100 + .2 * 100 * 1.05 ' Do first multiplication CustomerPrice = 100 + 20 * 1.05 ' Do second multiplication CustomerPrice = 100 + 21 ' Now do addition CustomerPrice = 121 ' Now do assignment
Therefore, you collect $121 from the customer, and he literally bolts out of the store amid the sounds of muffled laughter . Hmmm. Clearly, the item was sold too inexpensively because you let the natural precedence order resolve the equation.
The error arose because you need to figure the sales tax on the combination of the base price plus the markup. To save your equation, you need a way to alter the order of precedence you are using. You can do that with parentheses.
If arithmetic operators eat operands, parentheses are at the top of the food chain. In any complex expression that involves subexpressions, expressions that are surrounded by parentheses are resolved first, regardless of the operators in the subexpression they surround. For example, you can rewrite your pricing statement as follows:
CustomerPrice = (Cost + .2 * Cost) * 1.05
Because subexpressions in parentheses are processed first, you can see the impact that the parentheses have on the final assignment:
CustomerPrice = (Cost + .2 * Cost) * 1.05 CustomerPrice = (100 + .2 * 100) * 1.05 CustomerPrice = (100 + 20) * 1.05 CustomerPrice = (120) * 1.05 CustomerPrice = 126
Now the purchase price plus the tax has been calculated correctly.
Expressions contained within parentheses are resolved before expressions that are not in parentheses. In cases where there are two or more subexpressions in parentheses, the subexpressions are resolved according to the left-to-right rules of associativity. Consider the following complex statement:
X = (A + B) + (C / D) * (E F)
In this statement, all the values within the subexpressions in parentheses are resolved first. Supplying some numeric values helps you understand this process:
X = (10 + 5) + (100 / 2) * (50 48) ' Resolve parenthesized sub expressions X = 15 + 50 * 2 ' normal rules of precedence resume; multiplication X = 15 + 100 ' Now add X = 115 ' Now assign
Notice that after the expressions in parentheses are resolved, the normal precedence order takes over.