Over a million developers have joined DZone.

A Java Conversion Puzzler, Not Suitable For Work (or Interviews)

· Java Zone

Learn more about how the Java language, tools and frameworks have been the foundation of countless enterprise systems, brought to you in partnership with Salesforce.

A really hard interview question would be something like this

int i = Integer.MAX_VALUE;
i += 0.0f;
int j = i;
System.out.println(j == Integer.MAX_VALUE); // true

Why does this print true? 

At first glace, the answer seem obvious, until you realise that if you change int i for long ithings get weird

long i = Integer.MAX_VALUE;
i += 0.0f;
int j = (int) i;
System.out.println(j == Integer.MAX_VALUE); // false
System.out.println(j == Integer.MIN_VALUE); // true

What is going on you might wonder? When did Java become JavaScript?

Let me start by explaining why long gives a such a strange result.

An important detail about += is that it does an implicit cast.  You might think that

a += b;

is the same as

a = a + b;

and basically it is except with a subtle difference which most of the time doesn't matter;

a = (typeOf(a)) (a + b);

Another subtle feature of addition is the the result is the "wider" of the two types.  This means that

i += 0.0f;

is actually

i = (long) ((float) i + 0.0f);

When you cast Integer.MAX_VALUE to a float you get a rounding error (as float has a mantissa of 24-bits) resulting in the value being one more than what you started with.  i.e. it is the same as

i = Integer.MAX_VALUE + 1; // for long i

When you cast Integer.MAX_VALUE + 1 to an int again, you get an overflow and you have Integer.MIN_VALUE;

j = Integer.MIN_VALUE;

So why is that a long get the unexpected value, and int happens to get the expected value.

The reason is that when rounding from floating point to an integer it rounds down to 0, to the nearest representable value.  Thus

int k = (int) Float.MAX_VALUE; // k = Integer.MAX_VALUE;
int x = (int) (Integer.MAX_VALUE + 1.0f) // x = Integer.MAX_VALUE;

Note: Float.MAX_VALUE / Integer.MAX_VALUE is 1.5845632E29 which is a hell of an error, but the best int can do.

In short, for an int value Integer.MAX_VALUE, the statement i += 0.0f; causes the value to jump up one (casting to a float) and then down one (casting back to an int) so you get the value you started with.

Discover how the Force.com Web Services Connector (WSC) is a code-generation tool and runtime library for use with Force.com Web services, brought to you in partnership with Salesforce.


Published at DZone with permission of Peter Lawrey, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}