Reviewing Primitive Assignments – Working with Binary Arithmetic Operators – 1Z0-829 Study Guide

Reviewing Primitive Assignments

See if you can figure out why each of the following lines does not compile:

intfish =1.0;// DOES NOT COMPILE
short bird= 1921222;//DOESNOTCOMPILE
intmammal= 9f;//DOESNOTCOMPILE
long reptile = 192_301_398_193_810_323;// DOES NOT COMPILE
The first statement doesnot compile becauseyou are trying to assign a double 1.0

to an integer value. Even though the value is a mathematic integer, by adding .0, you’re instructing the compiler to treat it as a double. The second statement does not compile because the literal value 1921222 is outside the range of short, and the compiler detects this. The third statement does not compile because the f added to the end of the number instructs the compiler to treat the number as a floating-­point value, but the assignment is to an int. Finally, the last statement does not compile because Java interprets the literal as an int and notices that the value is larger than int allows. The literal would need a postfix L or l to be considered a long.

Applying Casting

We can fix three of the previous examples by casting the results to a smaller data type. Remember, casting primitives is required any time you are going from a larger numerical data type to a smaller numerical data type, or converting from a floating-­point number to an integral value.

int fish = (int)1.0;

short bird = (short)1921222; // Stored as 20678 int mammal = (int)9f;

What about applying casting to the last example?

long reptile = (long)192301398193810323; // DOES NOT COMPILE

This still does not compile because the value is first interpreted as an int by the compiler and is out of range. The following fixes this code without requiring casting:

long reptile = 192301398193810323L;

Overflow and Underflow

The expressions in the previous example now compile, although there’s a cost. The second value, 1,921,222, is too large to be stored as a short, so numeric overflow occurs, and it becomes 20,678. Overflow is when a number is so large that it will no longer fit within the

data type, so the system “wraps around” to the lowest negative value and counts up from

there, similar to how modulus arithmetic works. There’s also an analogous underflow, when the number is too low to fit in the data type, such as storing -200 in a byte field.

This is beyond the scope of the exam but something to be careful of in your own code. For example, the following statement outputs a negative number:

System.out.print(2147483647+1); // -­2147483648

Since 2147483647 is the maximum int value, adding any strictly positive value to it will cause it to wrap to the smallest negative number.

Let’s return to a similar example from the “Numeric Promotion” section earlier in the chapter.

short mouse = 10;

short hamster = 3;

short capybara = mouse * hamster; // DOES NOT COMPILE

Based on everything you have learned up until now about numeric promotion and casting, do you understand why the last line of this statement will not compile? As you may remember, short values are automatically promoted to int when applying any arithmetic operator, with the resulting value being of type int. Trying to assign a short variable with an int value results in a compiler error, as Java thinks you are trying to implicitly convert from a larger data type to a smaller one.

We can fix this expression by casting, as there are times that you may want to over-ride the compiler’s default behavior. In this example, we know the result of 10 * 3 is 30, which can easily fit into a short variable, so we can apply casting to convert the result back to a short:

short mouse = 10;

short hamster = 3;

short capybara = (short)(mouse * hamster);

By casting a larger value into a smaller data type, you instruct the compiler to ignore its default behavior. In other words, you are telling the compiler that you have taken additional steps to prevent overflow or underflow. It is also possible that in your particular application and scenario, overflow or underflow would result in acceptable values.

Last but not least, casting can appear anywhere in an expression, not just on the assign-ment. For example, let’s take a look at a modified form of the previous example:

short mouse = 10;

short hamster = 3;

short capybara = (short)mouse * hamster;

// DOES NOT COMPILE

So, what’s happening on the last line? Well, remember when we said casting was a unary operation? That means the cast in the last line is applied to mouse, and mouse alone. After the cast is complete, both operands are promoted to int since they are used with the binary multiplication operator (*), making the result an int and causing a compiler error.

What if we changed the last line to the following?

short capybara = 1 + (short)(mouse * hamster); // DOES NOT COMPILE

In the example, casting is performed successfully, but the resulting value is automatically promoted to int because it is used with the binary arithmetic operator (+).