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.

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