Over a million developers have joined DZone.

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

DZone's Guide to

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

· Java Zone
Free Resource

Just released, a free O’Reilly book on Reactive Microsystems: The Evolution of Microservices at Scale. Brought to you in partnership with Lightbend.

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.

Strategies and techniques for building scalable and resilient microservices to refactor a monolithic application step-by-step, a free O'Reilly book. Brought to you in partnership with Lightbend.


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

Opinions expressed by DZone contributors are their own.


Dev Resources & Solutions Straight to Your Inbox

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 }}