I try to write blogs whenever I get spare time

Just to let you know what I am trying to learn and what I am doing now.

Puzzle with long division

This post is all about a simple division of data type “Long”. Just have a look at the following code:

public class LongDivision

{

public static void main(String[] args)

{

final long MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000;

final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000;

System.out.println(MICROS_PER_DAY / MILLIS_PER_DAY);

}

}

What would be printed in the console after executing this code?

I am helping you a bit. According toSun, Long has a minimum value of -9,223,372,036,854,775,808 and a maximum value of 9,223,372,036,854,775,807 (inclusive). So both the two final variable’s value would fit perfectly, there should not be any overflow.

So, we should expect this code to print 1000. But, alas! to the great horror you would see this code to print 5!!!

What the heck with this dumb code?

Wait, here is the twist. The problem is that the computation of the constant MICROS_PER_DAY does overflow. Although the result of the computation fits in a long with room to spare, it doesn’t fit in an int.

Aren’t you thinking this is an absurd stuff? We declared the variable as long, why this poor long data needs to be fit in int?

The fact is that, when you use the int multiplication operation(*), the computation is performed entirely in int arithmetic, and only after the computation completes is the result promoted to a long. By then, it’s too late: The computation has already overflowed, returning a value that is too low by a factor of 200. The promotion from int to long is a widening primitive conversion [JLS 5.1.2].

So why is the computation performed in int arithmetic? Because all the factors that are multiplied together are int values. When you multiply two int values, you get another int value. Java does not have target typing, a language feature wherein the type of the variable in which a result is to be stored influences the type of the computation.

It’s easy to fix the program by using a long literal in place of an int as the first factor in each product. This forces all subsequent computations in the expression to be done with long arithmetic.

So the correct code would be like this:

public class LongDivision

{

public static void main(String[] args)

{

final long MICROS_PER_DAY = 24L * 60 * 60 * 1000 * 1000;

final long MILLIS_PER_DAY = 24L * 60 * 60 * 1000;

System.out.println(MICROS_PER_DAY / MILLIS_PER_DAY);

}

}

NB: Courtesy by “Joshua Bloch”. This puzzle has been taken from his book: “Java™ Puzzlers: Traps, Pitfalls, and Corner Cases“.

0 comments:

Post a Comment