0

As I am trying to compare these doubles, it won't seem to be working correctly

Here it goes: (This is exactly my problem)

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

int main () {
    int i_wagen;
    double dd[20];
    dd[0]=0.;
    dd[1]=0.;
    double abstand= 15.;
    double K_spiel=0.015;
    double s_rel_0= K_spiel;
    int i;

    for(i=1; i<=9; i++)
    {
        i_wagen=2*(i-1)+2;
        dd[i_wagen]=dd[i_wagen-1]-abstand;
        i_wagen=2*(i-1)+3;
        dd[i_wagen]=dd[i_wagen-1]-s_rel_0;
    }
    double s_rel=dd[3-1]-dd[3];

   if((fabs(s_rel) - K_spiel) == 0.)
   {
       printf("yes\n");
   }
   return(0);
}

After executing the programm, it wont print the yes.

sg7
  • 6,108
  • 2
  • 32
  • 40
Mohamed Azzam
  • 49
  • 2
  • 5

3 Answers3

0

You're comparing x to two different matrix entries: the first if compares x to coeff[0][0], the second to coeff[0][1]. So if x is greater than coeff[0][0] and less than or equal to coeff[0][1] the program will execture the final else branch. You probably want to compare x to the same matrix entry in both if statements. And in that case, the last else branch would be useless, since one of the three cases (less than, equal to or greater than) MUST be true.

Matthias Grün
  • 1,466
  • 1
  • 7
  • 12
  • that's not the case, i do want to to have it like that. What i want to know is, does it make a difference if i compare a double or an int? are there different procedures i need to take care of? – Mohamed Azzam Mar 21 '18 at 12:49
  • @MohamedAzzam please edit your question and provide a [mcve]!! – Jabberwocky Mar 21 '18 at 12:53
0

How to compare double variables in the if statement?

Take under account limited precision of the double representation of floating point numbers!

Your problem is simple and covered in Is floating point math broken?

Floating point operations are not precise. The representation of the given number may not be precise.

For 0.1 in the standard binary64 format, the representation can be written exactly as 0.1000000000000000055511151231257827021181583404541015625

Double precision (double) gives you only 52 bits of significant, 11 bits of exponent, and 1 sign bit. Floating point numbers in C use IEEE 754 encoding.

See the output of your program and the possible fix where you settle down for the variable being close to 0.0:

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

#define PRECISION  1e-6

int main (void) {

    int i_wagen;
    double dd[20];

    dd[0]=0.;
    dd[1]=0.;

    double abstand= 15.;
    double K_spiel=0.015;

    double s_rel_0= K_spiel;
    int i;

    for(i=1; i<=9; i++)
    {
        i_wagen = 2*(i-1)+2;

        dd[i_wagen] = dd[i_wagen-1]-abstand;
        i_wagen = 2*(i-1)+3;

        dd[i_wagen] = dd[i_wagen-1] - s_rel_0;
    }

    double s_rel = dd[3-1]-dd[3];

    printf(" s_rel %.16f K_spiel %.16f  diff  %.16f \n" , s_rel, K_spiel, ((fabs(s_rel) - K_spiel)) );

    if((fabs(s_rel) - K_spiel) == 0.0) // THIS WILL NOT WORK!
    {
       printf("yes\n");
    }

    //  Settle down for being close enough to 0.0     
    if( fabs( (fabs(s_rel) - K_spiel)) < PRECISION)
    {      
       printf("yes!!!\n");
    }

    return(0);
}

Output:

s_rel 0.0150000000000006 K_spiel 0.0150000000000000  diff  0.0000000000000006                                      
yes!!!
sg7
  • 6,108
  • 2
  • 32
  • 40
0

First, dd[i_wagen-1] as used in the statement:

dd[i_wagen]=dd[i_wagen-1]-abstand;

is uninitialized. Code will run, but will have unpredictable results. To initialize, you can use:

double dd[20]={0}; //sufficient

or possibly

double dd[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //explicit, but not necessary

Moving to your actual question, it all comes down to this statement:

if((fabs(s_rel) - K_spiel) == 0.)

You have initialized K_spiel to 0.015. And at this point in your execution flow s_rel appears to be close to 0.015. But it is actually closer to 0.0150000000000006. So the comparison fails.

One trick that is commonly used is to define an epsilon value, and use it to determine if the difference between two floating point values is small enough to satisfy your purpose:

From The Art of Computer Programming, the following snippet uses this approach, and will work for your very specific example: (caution: Read why this approach will not work for all floating point related comparisons.)

bool approximatelyEqual(float a, float b, float epsilon)
{
    return fabs(a - b) <= ( (fabs(a) < fabs(b) ? fabs(b) : fabs(a)) * epsilon);
}

So replace the line:

if((fabs(s_rel) - K_spiel) == 0.)

with

if(approximatelyEqual(s_rel, K_spiel, 1e-8)
ryyker
  • 22,849
  • 3
  • 43
  • 87