C and Fortran support mostly the same math operators, except that
Fortran supports exponentiation, which is done in C using the
pow()
library function.
Precedence and associativity in C and Fortran are the same as in algebra. Grouping () has the highest precedence, followed by negation (unary minus), then exponentiation, then multiplication and division, then addition and subtraction.
The C math operators are listed in Table 17.7, “Basic Math Operators in C”. C also has a number of additional operators for bitwise operations, since it is often used for systems programming, cryptography, etc. They are shown in Table 17.8, “Bitwise Operators in C”.
Table 17.7. Basic Math Operators in C
Operator | Operation | Precedence | Associativity / Order of Operation |
---|---|---|---|
() | Grouping | 1 (highest) | Inside to outside |
- | Negation | 2 | Right to left |
++ | Increment | 2 | Nearest to farthest |
-- | Decrement | 2 | Nearest to farthest |
* | Multiplication | 3 | Left to right |
/ | Division | 3 | Left to right |
% | Mod (remainder) | 3 | Left to right |
+ | Addition | 4 | Left to right |
- | Subtraction | 4 | Left to right |
[operator]= (=, +=, -=, etc.) | Assignment | 6 | Right to left |
Table 17.8. Bitwise Operators in C
Operator | Operation | Precedence | Associativity / Order of Operation |
---|---|---|---|
~ | Complement (invert all bits) | 2 (same as unary -) | Left to right |
<< | Shift left | 5 (below + and -) | Left to right |
>> | Shift right | 5 (below + and -) | Left to right |
& | Bitwise AND | 6 | Left to right |
^ | Bitwise XOR | 6 | Left to right |
| | Bitwise OR | 6 | Left to right |
[operator]= (=, +=, -=, etc.) | Assignment | 7 | Right to left |
The C shift operators can often be used in place of integer multiplication and division to greatly improve program speed. When we shift the digits of a decimal number one place to the left, it has the effect of multiplying the value by 10. Likewise, shifting to the right divides by 10.
The same principal applies to any other number base, including base 2, which is used to store integers internally. This works with both unsigned binary and 2's complement values. Hence, the following two statements are the same:
c = c * 8; c = c << 3; // Multiplies by 2, three times
The second statement may be significantly faster. A shift of any number of bits can occur within a single clock cycle in most modern CPUs, while multiplication may require many clock cycles. Some optimizers are smart enough to recognize which of your multiplications can be done with a shift and will generate a shift instruction automatically. However, it's best not to rely on such features. Using a shift instruction explicitly will ensure that your code is optimal no matter where it is compiled and executed.
The C increment and decrement operators are a convenient way to add 1 to or subtract 1 from a variable. The following two statements have the same effect:
++c; c++;
Like all C operators, increment and decrement operators can also be used within expressions, though. This often allows us to eliminate a separate statement for incrementing a counter variable, which improves code density.
When used this way, the value of the expression will depend on whether the ++ or -- comes before (pre-increment, pre-decrement) or after (post-increment, post-decrement) the variable. If it comes before, then the increment occurs before the value of the variable is used in the expression, and vice versa.
a = 1; b = 5 + ++a; // Pre-increment: b is now 7 and a is 2
a = 1; b = 5 + a++; // Post-increment: b is now 6 and a is 2
C also allows us to combine any binary (two-operand) operator with '=' to save typing in common situations. The following two statements are equivalent:
c = c + 7; c += 7;
This feature can also be used inside an expression, but must be parenthesized:
a = 1; b = 5 + (a += 10); // b is now 16 and a is 11
Fortran supports most common algebraic operators, including exponentiation:
Table 17.9. Basic Math Operators in Fortran
Operator | Operation | Precedence | Order of Operation |
---|---|---|---|
() | grouping | 1 (highest) | inside to outside |
** | exponentiation | 3 | right to left |
- | negation | 3 | right to left |
* | multiplication | 4 | left to right |
/ | division | 4 | left to right |
+ | addition | 5 | left to right |
- | subtraction | 5 | left to right |
Example 17.1. Precedence and Order of Evaluation
a + b + c equals (a + b) + c equals a + (b + c) a - b - c equals (a - b) - c does not equal a - (b - c) a ** b ** c equals a ** (b ** c) does not equal (a ** b) ** c
Unary minus is the same as multiplication by -1 or subtracting from 0, so -x equals -1 * x equals 0 - x.
Math operators are sensitive to the data types of the operands and may produce difference results for different types, i.e. they are polymorphic.
Recall from grade school that integer division and real division are not the same. Integer division results in an integer quotient and a remainder, while real division results in a different quotient and no remainder. ( The real quotient is the integer quotient + remainder / divisor. )
The C and Fortran divide operator (/) performs integer division if both operands are integers, and floating point division if either operand is floating point. Pay attention to the types of the operands when dividing, whether they are variables or constants.
int a = 5, b = 10; double x, y, z = 10; x = a / 2; // a and 2 are both integers, x = 2.0, remainder discarded y = a / 2.0; // 2.0 is floating point, y = 2.5 x = a / b; // a and b are both integers, x = 0.0, remainder discarded x = a / z; // z is floating point, x = 0.5
When using the division operator (/), care must be taken not to divide by zero.
Likewise, the exponentiation operator (**) cannot be used with negative bases and certain fractional exponents, unless working with complex numbers. For example, (-1) ** (0.5) does not exist in the real numbers, and hence will cause an error in Fortran.
What are the precedence and associativity rules for basic math operators in C and Fortran, compared with algebra?
How does bit shifting relate to multiplication and division?
Show a C statement that subtracts 1 from the variable x and adds the old value of x to y.
What is the value of y after each of the following statements?
int a = 1, b = 2, c = 3; double x = 4.0, y; y = a / b; y = c / b; y = c / x;