In my last post about arithmetic operators, I mentioned following up with a post about when the compound assignment operators don’t work as expected. The idea came to me because I was using the *= operator to multiply numbers in a loop and I was not getting the numbers I was expecting to get. That got me looking into whether it was possible for the compound operators to not work correctly. In the end, the reason for my problem was rather mundane: I wasn’t getting the answers I expected because I wasn’t starting with the numbers I thought I was.
Before we get started, let’s quickly review what a compound assignment operator is: a shorthand way to operate on a variable and assign the value back to itself.
int i = 1; i += 1;
Let’s define a byte and perform some operations on it:
byte b = 0; b += 1;
When we print out the value of b it’s equal to 1 just as we expect.
Let’s go a little bigger now:
b += 200;
When we print out the value of b we get… -55. We were expecting 201 right?
If we were to try the following, it wouldn’t even compile:
b = b + 200;
It turns out that according to the Java language specification for compound assignment operators that the casting is done automatically.
So b += 200 is actually equivalent to b = (byte) (b + 200) which as we’ve seen gives us weird results. Since bytes can only hold values between -128 and 127, we see these strange results.
For this example, I chose to use byte to keep the numbers small, but you could see similar issues with short and int if you’re working with large enough numbers.
In fact, it doesn’t take much to run into trouble with short either, especially if you’re multiplying:
short s = 5000; s *= 5000; System.out.println(s);
The example above gives us 30,784 instead of the 25,000,000 we were expecting.
The take away here is that we should be careful about the data types we choose when we’re using compound operators. The implicit casting that Java does when using them, means that the compiler isn’t going to save us. This is especially true when we’re using the *= and /= operators that can yield larger results more quickly.
2 thoughts on “Java Compound Assignment Operators: What Could Go Wrong?”
Hi, Am struggling to understand the program on compound expression. please help me out
how this expression is computed? Please explain
Wow – that expression is a wild ride. Is this a learning example from somewhere?
Let me see if I can explain what’s going on here. Assignment operators are shorthand. So x += y is equivalent to x = x + y. This example is hard to unravel because there are so many expressions. Assignment has the lowest precedence of any of the operators, so the arithmatic is done and then it’s assigned.
So for our example:
float x = 10, y = 20, z = 40;
We work back from right to left:
y -= z -> y = 20 – 40
y is now -20
x /= y -> x = 10 / -20
x would be -.5, but the left-most variable only gets assigned at the end, so the -.5 gets used, but x stays 10 for now
z/=x -> z = 40 / -.5
z is now -80
y += z -> y = -20 + -80
y is now -60
x += y -> x = 10 + -60
x is now -50 and that should be the output of the example you gave above given the values I provided.
I hope this helps to clarify things.
I would advise against combining compound assignment operators in the same expression because they are so hard to read and understand.