An arithmetic expression is a mathematical formula and in Java, they can only be used with primitives. They are typically used on the right-hand side of assignment statements (the "rvalue").
It is important to note that the result of the expression has to match the data type of the lvalue (the object on the left-hand side, which is the variable to be changed).
Here is a list of commonly-used operators in arithmetic expressions:
Arithmetic Operators
Operator | Meaning | Example |
* | multiplication | x * y |
/ | division | x / y |
% | modulus (takes the remainder) | x % y |
+ | addition | x + y |
- | subtraction | x - y |
++ | add 1 | x++ (this is a shorthand for x = x + 1;) |
-- | subtract 1 | x-- (this is a shorthand for x = x - 1;) |
Arithmetic operators have rules of precedence that specify which operators are applied first. The most useful rule is that parentheses are first. This means that if you are writing a complicated mathematical formula, you should use parentheses rather than rely on the rules of precedence to make sure our calculation is correct.
Rules of Precedence for Arithmetic Operators
For those at the same level of precedence, whichever operator is first in the expression (reading left to right) is applied first.
The operators ++ and -- work differently based on if they are before the variable or after the variable. If the ++ symbol is before the variable, it is incremented first, then the new value is used. If the ++ symbol is after the variable, the current value is used, then the variable is incremented. The pattern is the same for --, except the variable is decremented. Since traditional mathematical expressions do not have ++ and --, they can be very confusing in code. The best way to keep your code clear is to only use them in their own statements, like this:
Using ++
and --
x++; // increment x by adding 1
y--; // decrement y by subtracting 1
Arithmetic expressions in programming languages generally work the way most people expect them to work based on traditional mathematics.
However the plus sign works in unexpected ways in Java because it behaves differently depending on if you are "adding" numbers or "concatenating" strings.
Division also works in unexpected ways in Java because it behaves differently depending on if you are dividing integers or real numbers. Integer division will discard the decimal part by just throwing it away. This is called truncation, and unlike the way a person would logically change a decimal to an integer, the value is not rounded up. Below are some practice examples.
Integer vs Real Division
Evaluate each expression - what is the result? (We will go over the answers in class.)
Were you surprised at any of the answers? Let's examine more code.
Integer vs Real Assignment
int sum = 10;
int count = 4;
double average;
average = sum / count;
What value do you think is in the object average? Surprise - it is 2.0! Did you expect it to be 2.5? The reason it is not 2.5 is that the statement is executed in the following order:
Having the compiler convert your values for you is called implicit type conversion. As you can see in this example, you may not got exactly what you expected.
Although it is helpful to understand how implicit type conversion works, we are still left with a problem. What if we really do need to calculate an average, which should always be a real number, from two ints? The answer is to use casting, which is the syntax we use to explicitly tell the compiler to change an int to a double.
Calculating an Average Using Casting
int sum = 10;
int count = 4;
double average;
average = (double)sum / (double)count;
The cast is the (double). The cast is applied to whatever immediately follows it, so this assignment is executed in this order:
If the division is a mixture of ints and doubles, the compiler will change the integers to double (this is called promoting) and will perform real division. This means that we didn't really need to cast count to double, but like using parentheses, it doesn't hurt to use it because it does make the code's intent very clear.
There are complicated rules about when you can cast, but the most important one for us to follow right now is that you should only cast a primitive value to another primitive type. Changing between other kinds of data types, such as from a String to a double, cannot be done with casting. That drastic of a change is called converting, not casting, and is done using the type-wrapper classes and method calls shown in the previous section.
Below are some more example assignment statements that use casting:
More Casting
For each assignment, what value is stored in the object? (We can go over the answers in class.)
double x;
x = 10/4;
double x;
x = (double)10/4;
double x;
x = (double)(10/4);
int x;
x = 10/(double)4;