Question

To compare two double type variables in C, I have defined #define EQUALITY_EPSILON = 1e-8. I am doing the comparison as follows:

if((img_score[i] - img_score[j]) >= EQUALITY_EPSILON){
    // handle for ith score greater than jth score
}
else if((img_score[j] - img_score[i]) >= EQUALITY_EPSILON){
    // handle for ith score smaller than jth score
}
else{
    // handle for ith score equal to jth score
}

The problem I am facing is that the scores in my code are extremely small, therefore for EQUALITY_EPSILON = 1e-8, the result of comparison turns out to be equality in some cases. My question is how small can I set EQUALITY_EPSILON?

Was it helpful?

Solution

Floating point numbers aren't spread out evenly on the number line. They're very dense around 0, and as the magnitude increases, the 'delta' between two expressible values increases:

                               0
|      |     |    |   |  |  | ||| |  |  |   |    |     |      |

This means, for small numbers, you need to use a smaller 'epsilon'.

(EDIT: And the error, or epsilon you allow for should be in the same range as the error you already expect in the values you are comparing. i.e. Errors due to the floating point operations that produced them. See comments below for why. /EDIT).

One fair indication of the kind of 'epsilon' you need to use can be had from nextafter in math.h:

nextafter(x, y) returns the next representable value after x, when travelling along the number line, in the direction of y.

Another way to do it would be to calculate the difference in magnitude between img_score[i] and img_score[j], and seeing how small it is compared to the magnitude of img_score[i] or img_score[j]. How much smaller? You need to decide.

OTHER TIPS

You should not be using an absolute value for the epsilon. The value chosen should be relative to the values you're comparing.

For example, you can divide the smallest (closest to zero) by one million and use the absolute value of that.

Whether that's a suitable choice depends on what operations were performed to reach the values. It may not be suitable for all cases.

The smallest absolute value for a double is 2^{-1023}, which is around 10^{-308}. But there are only 53 bits for storing the mantissa (the part where your significant digits are). If you know in advance the approximate value of the difference, then you can go almost as low as 2^{-53} times that difference for your epsilon. If you don't know in advance, you should probably build your epsilon as a percentage of one of the differences.

Note that going down to 2^{-53} times the difference is the limit caused by the limited precision in the double. If the two values you are subtracting are so close to each other that you have fewer than 53 significant bits in their difference, your epsilon could only go as low as 2^{-x} times the difference, where x is the number of significant bits in the difference.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top