0

Possible Duplicate:
Most effective way for float and double comparison

In my program some double variables take values of the form 1.00000001. Equality check of these variables with 1 obviously fails.

I wanted to know how can I reduce the precision of double type variables in c, so that equality with integers works.

4
  • What would be the intended behavior if the value is 1.5 ? Commented Jul 5, 2012 at 14:43
  • 3
    stackoverflow.com/questions/17333/… Commented Jul 5, 2012 at 14:44
  • @J.N. For 1.5 equality should return false. Let us say, anything after fifth decimal place should be ignored. Commented Jul 5, 2012 at 14:46
  • Why the fifth decimal place? There are two problems with that. First, a number very slightly below 1.00001 and a number very slightly above 1.00001 will be reported as not equivalent even though you might want otherwise (because they differ only because of rounding errors, not because of actual difference if computed with mathematical exactness). Second, you should have a basis for setting the threshold for considering numbers to be equivalent. You should know how much error can be produced in the values you are comparing and how much error your decision can tolerate. Commented Jul 5, 2012 at 14:54

5 Answers 5

3

You should almost never check floating point values for exact equality, expecially when they comes from comutation. You should check the absolute value of the difference from the compare value being less than a certain epsilon. The "precision" of the double is given by the internal number representation and you can't change it. How to exactly choose epsilon can be difficult, there is some comment to that answer discussing that, read it, but you eventually come with the pratical epsilon based equality.

Sign up to request clarification or add additional context in comments.

10 Comments

The double variables are returned by a linear program, therefore I can't do without the equality check.
The question linked by @Lucas suggest being extremely careful when doing so.
@stressed_geek you just have to change your if from == to abs(a-x) < epsilon ...
this suggestion is wrong in many ways, abs(a-x) < epsilon is a good idea only for numbers close to zero (both a and x) otherwise relative epsilon or ulps. And you sometimes have to compare doubles using ==
@unkulunkulu I agree, but you'd better say why ;)
|
2

There's no portable way, no.

With the GNU C library, you can use this API to change the rounding mode.

But in general, it's better to express it with code, so that your expectations become clear and portable:

#define EQUALITY_EPSILON 1e-3  /* Or whatever. */

if(fabs(x - y) <= EQUALITY_EPSILON)
{
}

Comments

1

You should avoid checking for equality in floating-point comparisons. Instead, use a precision value epsilon like so:

if (fabs(a - b) < epsilon)
{
    // treat a and b as equal
}

The choice of epsilon is probably complicated, but my knowledge doesn't go that far.

Do a Google search for "What Every Programmer Should Know About Floating-Point Arithmetic". It's a well-known article that covers all this stuff.

2 Comments

This is absolutely not correct code. abs is the integer absolute value function. The floating-point value a-b will be converted to integer (by truncation), and the absolute value of that will be compared to epsilon. Any value of a-b less than 1 will be reported as less than epsilon, regardless of how small epsilon is (as long as it is positive). The correct function to use is fabs.
Oops, I'm used to C++ where it's overloaded. Fixed in edit.
0

It doesn't make a lot of sense to 'reduce the precision of double type variables'. You should probably think instead of using functions such as ceil, floor, and round to make an integer out of your double in a way that you have good control over and then use that integer in your comparisons.

Comments

0

in C99

#include <stdio.h>
#include <math.h>

int main(){
    double d = 1.00000001;
    int i = (int)round(d);

    printf("%d\n", i);

    return 0;
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.