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…