Module 2.3 - Arithmetic Operators and the Hierarchy of Priorities
Arithmetic Operators in Python
+, -, *, /, //, %, **
Expressions The simplest expression is a literal itself
Data and operators when connected together form
Division by zero doesn't work
Do not try to: - perform a division by zero; - perform an integer division by zero; - find a remainder of a division by zero.
Floor Division
Integer division can also be called
List of Priorities
Priority -- Operator 1 -------- ** 2 ------- +, - (note: unary operators located next to the right of the power operator bind more strongly) | Unary 3 ------- *, /, //, % 4 ------- +, - | Binary print(2 * 3 % 5) output: 1
The Hierarchy of Priorities
The phenomenon that causes some operators to act before others is known as
Parenthesis
can change the natural order of a calculation
The binding of the operator --------------------------------- The two possible results are: 2 ** 2 → 4; 4 ** 3 → 64 2 ** 3 → 8; 2 ** 8 → 256 Run the code. What do you see? The result clearly shows that the exponentiation operator uses right-sided binding.
determines the order of computations performed by some operators with equal priority, put side by side in one expression. Most of Python's operators have left-sided binding, which means that the calculation of the expression is conducted from left to right. This simple example will show you how it works. Take a look: print(9 % 6 % 2) output: 1 There are two possible ways of evaluating this expression: from left to right: first 9 % 6 gives 3, and then 3 % 2 gives 1; from right to left: first 6 % 2 gives 0, and then 9 % 0 causes a fatal error -------------------------------- print(2 ** 2 ** 3) output: 256
An Expression
is a combination of values (or variables, operators, calls to functions ‒ you will learn about them soon) which evaluates to a certain value, e.g., 1 + 2.
Operator For example, just as in arithmetic, the + (plus) sign is the operator which is able to add two numbers, giving the result of the addition
is a symbol of the programming language, which is able to operate on the values.
Unary Operator note: a unary operator to the right of the exponentiation operator binds more strongly, for example: 4 ** -1 equals 0.25
is an operator with only one operand, e.g., -1, or +3.
Rounding always goes to the
lesser integer
Binary Operator
operator is an operator with two operands, e.g., 4 + 5, or 12 % 5.
Operators and parentheses Of course, you're always allowed to use parentheses, which can change the natural order of a calculation. In accordance with the arithmetic rules, subexpressions in parentheses are always calculated first. You can use as many parentheses as you need, and they're often used to improve the readability of an expression, even if they don't change the order of the operations. An example of an expression with multiple parentheses is here:
print((5 * ((25 % 13) + 100) / (2 * 13)) // 2) output: 10.0
there is also a unary + operator. You can use it like this The operator preserves the sign of its only argument - the right one. Although such a construction is syntactically correct, using it doesn't make much sense, and it would be hard to find a good rationale for doing so
print(+2) output: 2
The addition operator is the + (plus) sign, which is fully in line with mathematical standards.
print(-4 + 4) print(-4. + 8) output: 0 4.0
The subtraction operator is obviously the - (minus) sign, although you should note that this operator also has another meaning - it can change the sign of a number. This is a great opportunity to present a very important distinction between unary and binary operators. In subtracting applications, the minus operator expects two arguments: the left (a minuend in arithmetical terms) and right (a subtrahend). For this reason, the subtraction operator is considered to be one of the binary operators, just like the addition, multiplication and division operators. But the minus operator may be used in a different (unary) way - take a look at the last line of the snippet below:
print(-4 - 4) print(4. - 8) print(-1.1) output: -8 -4.0 -1.1
Distinction between unary and binary operators. In subtracting applications, the minus operator expects two arguments: the left (a minuend in arithmetical terms) and right (a subtrahend). For this reason, the subtraction operator is considered to be one of the binary operators, just like the addition, multiplication and division operators. But the minus operator may be used in a different (unary) way - take a look at the last line of the snippet below: The operator preserves the sign of its only argument - the right one. Although such a construction is syntactically correct, using it doesn't make much sense, and it would be hard to find a good rationale for doing so
print(-4 - 4) print(4. - 8) print(-1.1) output: -8 -4.0 -1.1 ------------------------- print(+2) output: 2
% remainder (modulo) The next operator is quite a peculiar one, because it has no equivalent among traditional arithmetic operators. Its graphical representation in Python is the % (percent) sign, which may look a bit confusing. Try to think of it as of a slash (division operator) accompanied by two funny little circles. The result of the operator is a remainder left after the integer division. In other words, it's the value left over after dividing one value by another to produce an integer quotient. Note: the operator is sometimes called modulo in other programming languages. As you can see, the result is two. This is why: 14 // 4 gives 3 → this is the integer quotient; 3 * 4 gives 12 → as a result of quotient and divisor multiplication; 14 - 12 gives 2 → this is the remainder.
print(14 % 4) output: 2 ---------------------- print(12 % 4.5) output: 3.0 3.0 - not 3 but 3.0 (the rule still works: 12 // 4.5 gives 2.0; 2.0 * 4.5 gives 9.0; 12 - 9.0 gives 3.0)
An * (asterisk) sign is a multiplication operator
print(2 * 3) print(2 * 3.) print(2. * 3) print(2. * 3.) Output: 6 6.0 6.0 6.0
A ** (double asterisk) sign is an exponentiation (power) operator. Its left argument is the base, its right, the exponent.
print(2 ** 3) print(2 ** 3.) print(2. ** 3) print(2. ** 3.) Output: 8 8.0 8.0 8.0
A / (slash) sign is a divisional operator. The value in front of the slash is a dividend, the value behind the slash, a divisor. The result produced by the division operator is always a float, regardless of whether or not the result seems to be a float at first glance: 1 / 2, or if it looks like a pure integer: 2 / 1.
print(6 / 3) print(6 / 3.) print(6. / 3) print(6. / 3.) output: 2.0 2.0 2.0 2.0
A // (double slash) sign is an integer divisional operator. It differs from the standard / operator in two details: - its result lacks the fractional part - it's absent (for integers), or is always equal to zero (for floats); this means that the results are always rounded; - it conforms to the integer vs. float rule. As you can see, integer by integer division gives an integer result. All other cases produce floats ------------------------------ Imagine that we used / instead of // - could you predict the results? Yes, it would be 1.5 in both cases. That's clear. What we get is two ones - one integer and one float. The result of integer division is always rounded to the nearest integer value that is less than the real (not rounded) result. This is very important: rounding always goes to the lesser integer ------------------------------ Note: some of the values are negative. This will obviously affect the result. But how? The result is two negative twos. The real (not rounded) result is -1.5 in both cases. However, the results are the subjects of rounding. The rounding goes toward the lesser integer value, and the lesser integer value is -2, hence: -2 and -2.0.
print(6 // 3) print(6 // 3.) print(6. // 3) print(6. // 3.) output: 2 2.0 2.0 2.0 -------------------------------------------- print(6 // 4) print(6. // 4) output: 1 1.0 ------------------------------------------- print(-6 // 4) print(6. // -4) output: -2 -2.0
The exponentiation operator uses
right-sided binding, e.g., 2 ** 2 ** 3 = 256.
Subexpressions
subexpressions in parentheses are always calculated first
when at least one ** argument is a float,
the result is a float too
when both ** arguments are integers,
the result is an integer too