Summary
An arithmetic expression is not computed from left to right as it is read, but according to a hidden structure, its tree, which is fixed by the precedence of the operators, their associativity and the parentheses; and at each node of that tree the type of the operands decides which operation is performed, so that 7 / 2 is 3 and 7 / 2.0 is 3.5. This lesson studies the five arithmetic operators of C++ with integers and with reals; integer division and the remainder, which since C++11 truncate toward zero, from which it follows that the remainder takes the sign of the dividend and differs from the remainder of Euclidean division when the dividend is negative; the way to obtain the Euclidean remainder; the tree of an expression; the type of the result when the operands are of different types, and the two ways in which an integer arithmetic expression loses its meaning: dividing by zero and overflowing in an intermediate computation.
Learning objectives
- Compute the quotient and the remainder of integer division in C++, also with negative operands, and relate them to the quotient and the remainder of Euclidean division.
- Draw the tree of an arithmetic expression according to precedence and associativity, and compute its value.
- Predict the type of the result of an operation between operands of different types.
- Use integer division and the remainder to break quantities down: the digits of a number, a duration in hours and minutes, a day of the week.
The arithmetic operators
C++ has five binary arithmetic operators: addition +, subtraction -, multiplication *, division / and remainder %; it also has the unary minus, which changes the sign of its only operand, as in -x, and a unary plus, +x, which leaves it as it is. The first four apply to integers and to reals; the remainder, only to integers. Now, the same notation does not designate the same operation in every case: if both operands of / are integers, the division is integer division and its result is an integer, the quotient without its fractional part; if either of them is real, the division is real. The lesson Characters, Booleans, conversions and constants showed the most visible consequence of this rule, that double r{7 / 2}; stores 3: the division was done between integers before the result was converted to a real.
The program applies the five operators to 17 and 5, and repeats the division with a real dividend.
#include <print>int main(){ const int a{17}; const int b{5}; std::println("{} + {} = {}", a, b, a + b); std::println("{} - {} = {}", a, b, a - b); std::println("{} * {} = {}", a, b, a * b); std::println("{} / {} = {}", a, b, a / b); std::println("{} % {} = {}", a, b, a % b); const double x{17.0}; std::println("{} / {} = {}", x, b, x / b);}17 + 5 = 2217 - 5 = 1217 * 5 = 8517 / 5 = 317 % 5 = 217 / 5 = 3.417 divided by 5 gives 3 with 2 left over: they are the quotient and the remainder of sharing 17 objects out in groups of 5. The last line divides a real by an integer and obtains 3.4. Note that std::println writes the real 17.0 as “17”: the empty placeholder writes the shortest representation of the value, so what is written does not reveal the type; to see it, one asks for decimals with {:.1f}.
The % operator does not accept reals. Writing 7.5 % 2 is not a logic error that the program discovers when it runs, but a compilation error: the compiler says that operands of types double and int are invalid for the operator.
#include <print>int main(){ std::println("{}", 7.5 % 2);}main.cpp: In function ‘int main()’:main.cpp:5:28: error: invalid operands of types ‘double’ and ‘int’ to binary ‘operator%’ 5 | std::println("{}", 7.5 % 2); | ~~~ ^ ~The remainder of a real division does exist, and it is computed by the function std::fmod from the header <cmath>, which will be studied in the lesson Bits and the math library, together with exponentiation: C++ has no exponentiation operator, and 2 ^ 3 is not 8, but something else that will be explained there.
Loading the content…
Completed
Sign in to save your progress