The implicit cast you were not expecting in Java

LMAX Exchange

When you learn Java or any other programming language you usually start by looking at the basics of the type system and how the arithmetic operations work.  You learn how numbers are represented and what types of numbers your programming language offers to you.

At the same time, one of the first rules that you learn in Java is that implicit casting only occurs when you are doing a “safe” conversion, otherwise you need to explicitly tell your compiler that you understand what you are doing. You will often read things like

"In Java, only safe implicit conversions are performed: upcasts and promotion."

Source: StackOverflow
"Implicit type casting occurs only in the case of widening conversion or up casting."

Source: Learn2Geek

So, let’s focus on a non trivial and non safe conversion. Let’s say that we have an expression with type double and we want to assign the result to a long variable. There is no way the compiler can figure out automagically, in a safe way, how to convert a decimal number into a integer number without potentially losing some information. That’s clear, right?

"A conversion from type double to type long requires a non-trivial translation from a 64-bit floating-point value to the 64-bit integer representation. Depending on the actual run-time value, information may be lost."

Source: Java SE 8 Specification

So, the following piece of code will not compile in Java, as you will expect:

double a = 0.33;
long b = 10;
b = a * b;

The reason why this is not going to compile is because when you do (b = a * b) you are losing precision and that requires an explicit cast.

The trap

We have also learnt that you can write b = a * b in a more concise way by writing b *= a. The operator *= is a Compound Assignment Operators and most of the people (including me) understand that as a nice “syntactic sugar”.

So let’s try to rewrite our fragment using the operator *= .

double a = 0.33;
long b = 10;
b *= a;

Did you see what happened? OMG! The code just compiles! It does not just compile, it is also not going to fail in runtime and is going to lose precision silently.

Looking for an explanation

As my good colleague Siam Rafiee pointed out to me, the Java 8 SE Specification explain why that happens. If you look at the section 15.26.2. Compound Assignment Operators you will find a clear explanation of how the operator *= is going to be evaluated…

E1 op= E2 is equivalent to E1 = (T) ((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once

That means that what we have asked the compiler to do by using the *= operator is basically

b = ((long)(a * b));

So, if you were not yet aware, be very careful with the primitive Java type system. Happy coding!

Any opinions, news, research, analyses, prices or other information ("information") contained on this Blog, constitutes marketing communication and it has not been prepared in accordance with legal requirements designed to promote the independence of investment research. Further, the information contained within this Blog does not contain (and should not be construed as containing) investment advice or an investment recommendation, or an offer of, or solicitation for, a transaction in any financial instrument. LMAX Group has not verified the accuracy or basis-in-fact of any claim or statement made by any third parties as comments for every Blog entry.

LMAX Group will not accept liability for any loss or damage, including without limitation to, any loss of profit, which may arise directly or indirectly from use of or reliance on such information. No representation or warranty is given as to the accuracy or completeness of the above information. While the produced information was obtained from sources deemed to be reliable, LMAX Group does not provide any guarantees about the reliability of such sources. Consequently any person acting on it does so entirely at his or her own risk. It is not a place to slander, use unacceptable language or to promote LMAX Group or any other FX and CFD provider and any such postings, excessive or unjust comments and attacks will not be allowed and will be removed from the site immediately.