Beware of Java’s inconsistent MIN_VALUE

An astute user of my Tektosyne library noticed that I had made a simple but disastrous copy-paste mistake regarding the floating-point versions of some basic algorithms, such as finding the maximum of an array of numbers.

The integral versions initialize the return value to e.g. Integer.MIN_VALUE and then check for any greater values. I copied that code over directly to the floating-point versions, changing only the types. And then I neglected to include negative values in my unit tests. Boom.

In a stunning feat of API inconsistency, Java’s Float and Double versions of MIN_VALUE mean something totally different than the integral versions, even though their MAX_VALUE versions are equivalent. Here are the definitions on all primitive-wrapping classes, except for Character which has no negative values.

Class MAX_VALUE MIN_VALUE
Byte, Short, Integer, Long Positive value of greatest magnitude Negative value of greatest magnitude
Float, Double Positive value of greatest magnitude Positive value of smallest magnitude!

As a matter of fact, Float and Double don’t even have constants for the negative value of the greatest magnitude. If you want a ready-made constant that compares less than any given floating-point number, you’ll have to use NEGATIVE_INFINITY instead. That’s not exactly the same as integral MIN_VALUE but just as good for purposes such as finding maxima.

In the upcoming Tektosyne update I’ve accordingly changed all such uses of MIN_VALUE to NEGATIVE_INFINITY, also changed any corresponding uses of MAX_VALUE to POSITIVE_INFINITY for symmetry, and finally introduced negative numbers to all unit tests of such algorithms. The latter is of course what I should have done all along, but these algorithms were so short and simple I thought they hardly needed testing to begin with. Well…

Leave a Reply