Ever face the problem of having a float, and wanting to do a ton of stuff depending on its value? If somewhere in your brain started screaming after reading that, well, you’re in the right place.
Java’s switch keyword can only take char, byte, short, and int primitive types; their class equivalents java.lang.Character, java.lang.Byte, java.lang.Short, and java.lang.Integer; a java.lang.String; or an enum (JLS 20 § 14.11).
What it can’t do is take a float or a java.lang.Float. But we can ignore this measly restriction.
The Float class, since 1.3, has had a function that we can abuse. Float#floatToIntBits(float) lets us give it a float, and it will return what the IEEE-754 standard says are the bits, but as an int. And the int is what we can switch with, if we know the values we want.
Here’s an example of what I’ve done in my code. It’s meant to switch over five values, returning an enum constant, defaulting to returning ZERO.
return switch(Float.floatToIntBits(f)) {
case 0xc2340000 -> NEGATIVE_FORTY_FIVE;
case 0xc1b40000 -> NEGATIVE_TWENTY_TWO_POINT_FIVE;
case 0x41b40000 -> POSITIVE_TWENTY_TWO_POINT_FIVE;
case 0x42340000 -> POSITIVE_FORTY_FIVE;
default -> ZERO;
}
It would be easy to write it with ifs and elses, but that also makes it a bit harder to read it all.
if (f == -45f) {
return NEGATIVE_FORTY_FIVE;
} else if (f == -22.5f) {
return NEGATIVE_TWENTY_TWO_POINT_FIVE;
} else if (f == 22.5f) {
return POSITIVE_TWENTY_TWO_POINT_FIVE;
} else if (f == 45f) {
return POSITIVE_FORTY_FIVE;
} else {
return ZERO;
}
Returning to the screaming, there are some things to note.
- Zero and infinity are both signed, and two different bit values constitute both.
- IEEE 754 has a lot of bits that are equivalently NaN.
- Without writing constants, you’re going to have lots of magic numbers.
So long as you’re aware of the caveats, go on and switch to your heart’s content.