I spent about 2 hours tracking down a bug today and I would've found it much quicker had java thrown an exception when comparing NaN with a float. It would be nice if I could protect myself from this in the future. Any help is appreciated.
An exception should be thrown when a function experiences a failure, i.e., an error. A function is a unit of work, and failures should be viewed as errors or otherwise based on their impact on functions.
Using the Throws keyword Throws is a keyword used to indicate that this method could throw this type of exception. The caller has to handle the exception using a try-catch block or propagate the exception. We can throw either checked or unchecked exceptions.
All methods use the throw statement to throw an exception. The throw statement requires a single argument: a throwable object. Throwable objects are instances of any subclass of the Throwable class.
Only checked exceptions are required to be thrown using the throws keyword. Unchecked exceptions don't need to be thrown or handled explicitly in code.
The JVM instruction set reference specifically disallows the byte codes that do floating point math from throwing exceptions and rigidly specifies how they should work when NaN is an operand. If there is a way to do this, it will either require you to explicitly throw exceptions on NaN or to use a custom compiler to insert these checks for you.
One option that might be helpful would be to write a function like this:
public static float check(float value) {
if (Float.isNaN(value))
throw new ArithmeticException("NaN");
return value;
}
With this, you can write code to this effect:
float f = check(myOtherFloat / yetAnotherFloat);
This will then do the computation and throw on an error. Ideally with a short function name it won't be too obtrusive.
W
The protection in float or double is to make the result NaN or false. If you want to detect NaN, you are better of preventing the value in the first place e.g 0/0. When you do a division, check for 0 as a divisor and throw an Exception if it is. You can wrap this with a helper method to simplify.
public static double div(double a, double b) {
if(b == 0) throw new IllegalArguementException();
return a / b;
}
If I know the value could be 0 or more only, I often add a bias like
double d = a / (b + 1e-9);
This never produces NaN provided b >= 0. If a == 0, d == 0. The bias to use depends on the situation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With