I have an algorithm which uses floats
or doubles
to perform some calculations.
Example:
double a;
double b;
double c;
...
double result = c / (b - a);
if ((result > 0) && (result < small_number))
{
// result is relevant...
} else {
// result not required...
}
Now, I am worried about (b - a)
might be zero. If it is close to zero but not zero, it does not matter because the result
will be out of range to be useful, and I already detect that (as (b - a)
approaches zero, result
will approach +/- inf, which is not in the range 0
-small_number
...)
But if the result of (b - a)
is exactly zero, I expect that something platform dependant will happen due to divide by zero. I could change the if
statement to:
if ((!((b-a) == 0.0)) && ((result = c/(b-a)) > 0) && (result < small_number)) {
but I don't know if (b-a) == 0.0
will always detect equality with zero. I have seen there are multiple representations for exact zero in floating point? How can you test for them all without doing some epsilon check, which I don't need (a small epsilon will be ignored in my algorithm)?
What is the platform independant way to check?
EDIT:
Not sure if it was clear enough to people. Basically I want to know how to find if an expression like:
double result = numerator / denominator;
will result in a floating point exception, a cpu exception, a signal from the operating system or something else.... without actually performing the operating and seeing if it will "throw"... because detecting a "throw" of this nature seems to be complicated and platform specific.
Is ( (denominator==0.0) || (denominator==-0.0) ) ? "Will 'throw'" : "Won't 'throw'";
enough?
float and double both have varying capacities when it comes to the number of decimal digits they can hold. float can hold up to 7 decimal digits accurately while double can hold up to 15. Let's see some examples to demonstrate this.
As 0.1 cannot be perfectly represented in binary, while double has 15 to 16 decimal digits of precision, and float has only 7 . So, they both are less than 0.1 , while the double is more close to 0.1 .
First of all you should know that 0.4 and 0.5 are double constants while 0.4f and 0.5f are floating point constants.
It depends on how b
and a
got their values. Zero has an exact representation in floating point format, but the bigger problem would be almost-but-not-quite zero values. It would always be safe to check:
if (abs(b-a) > 0.00000001 && ...
Where 0.00000001 is whatever value makes sense.
Here's how you do it: instead of checking for (result < small_number)
, you check for
(abs(c) < abs(b - a) * small_number)
Then all your troubles disappear! The computation of c/(b-a)
will never overflow if this test is passed.
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