Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

float/double equality with exact zero

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?

like image 443
Bingo Avatar asked Mar 03 '12 00:03

Bingo


People also ask

Can float and double be equal?

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.

Is 0.1 float or double?

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 .

Is 0.5 a float or double?

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.


2 Answers

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.

like image 56
wallyk Avatar answered Oct 05 '22 12:10

wallyk


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.

like image 23
TonyK Avatar answered Oct 05 '22 12:10

TonyK