Main Tutorials

Java’s silent killer – Integer Overflow, Careful !

Believe it or not, Java contains Integer buffer overflow as well. I’m not sure is this the correct word to describe it or not, may be you can suggest some 🙂

OK, please take a look at below program, this program print the number of microseconds in a day.


public class JavaLongOverflow {

    public static void main(String[] args) {

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

        System.out.println("MICROS_PER_DAY : " + MICROS_PER_DAY);
       
    }

}

Result


MICROS_PER_DAY : 500654080

Oh.. the answer is 500654080. Wait.. is the answer correct? The correct answer should be 86400000000 !!! Why Java will give me an inaccurate result? where is this number come from? What happened exactly?

I do believe this is cause by an “int” overflow. Yes, the “long MICROS_PER_DAY” variable has enough space to fit in large number like 86400000000, but it doesn’t fit in an “int”! The maximum number of an “int” is 2147483647. Look careful of the program above, the whole arithmetic is in “int”, the result promoted to a long and assign to “long MICROS_PER_DAY” variable. According to [JLS 5.1.2], the promotion from int to long is cited as widening primitive conversion which preserves the (incorrect) numerical value.

However we can avoid above silent killer overflow by explicit the “long” in the first integer to force whole operation become a long arithmetic.


public class JavaLongOverflow {

    public static void main(String[] args) {

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

        System.out.println("MICROS_PER_DAY : " + MICROS_PER_DAY);
       
    }

}

Result


MICROS_PER_DAY : 86400000000

Above program prints 86400000000 as expected

Conclusion

This bug is so so difficult to detect or aware of. Sometime it’s even impossible to detect it. If someone make this kind of mistake in financial system, i just cant imaging the consequent. My only advice is to explicitly cast the primitive type when deal with calculation of two different type of primitive type. Always avoid to automatically widening primitive conversion in any calculation.

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
3 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
noname
14 years ago

The conclusion is: you don’t know what a buffer overflow is.

xavier
11 years ago

Hi Mkyong,

Do you know any way to prevent the overflow from happening (like automatically raising an ArithmeticException or something like this)?

I could use BigInteger everywhere but it is a bit clumsy.