Jump to content
  • Advertisement
ICanC

C++ comparing 2 floats

Recommended Posts

hi all, I'm testing with floats for the first time and have discovered that you can't compare 2 floats due to rounding errors. I've read online that you must use an epsilon and test for less than, however I don't seem to be able to get it working with the below code. - when running the code below it it is looping through 6 floats testing for equality with f entered by the player, but even if I put something totally different from the options, the message "not a valid position" is never executed

 

void locks::try_lock()
{
    print("\nEnter lock position: ");
    float f; cin >> f;
    int fexists = 1;
    float epsilon = 0.0000001; // Not sure what the best value to put here is?
    for (float &a : this->answers)
    {
        if ((a - f) < epsilon)
        {
        fexists = 0;
        }
    }
    if (fexists == 1)
    {
        cout << endl << f << " is not a valid position\n\n";
        Sleep(2000);
        return;
    }
}

 

Edited by ICanC

Share this post


Link to post
Share on other sites
Advertisement

At least: You need to use the absolute value of the difference, something like

  if (fabs(a-f) < epsilon)

or else you check whether a is greater than f and is close to f or a is lesser than f regardless how close. 

Edited by haegarr

Share this post


Link to post
Share on other sites

Is your logic backwards?

You have a "boolean" you set to "true" (in C++ we actually have types and constants for that, using them can make it easier to reason about logic).  You iterate through a list of values comparing them to your input value, and if at least one of the values matches, you set the "boolean" to "false" to indicate f is in the list.  If that "boolean" named fexists is still "true" by the end of the loop, it indicates f does not exist.

I  realize it doesn't answer you question, but...

Share this post


Link to post
Share on other sites

thanks haegarr, that fixed it.

 

and thanks Bregma, my logic was backwards, when writing that code I was wrongly thinking that 'return 0' indicates a 'true' and successful end to the program, when it is infact true values that indicate failure

Share this post


Link to post
Share on other sites

Your epsilon value is really too small to do meaningful general float comparisons.  floats are only 32bits, so there are not enough bits for that precision especially with larger float numbers.

A value of 0.0001 would work better but be WARNED! there are many situations where this is still a problem and in general you don't want a fixed epsilon value as larger float numbers have less precision.

Also you need to consider things like

float EPLISON = 0.0001f;

float a = 123.00015f;
float b = 123.0001f;

if (fabs(a - b) < EPLISON)
{
  std::cout << "Same" << std::endl;
}

float d = a * 100.0f;
float e = b * 100.0f;


if (fabs(d - e) < EPLISON)
{
  std::cout << "Same" << std::endl;
}

 

In this case a ==b but c!=d  although c = 100*a and d = 100*b

See here about float comparison problems

 
 
 

 

Edited by desiado

Share this post


Link to post
Share on other sites
3 hours ago, ICanC said:

I was wrongly thinking that 'return 0' indicates a 'true' and successful end to the program, when it is infact true values that indicate failure

When returning from main(), I recommend using EXIT_SUCCESS/EXIT_FAILURE. These are unambiguous, and will map to whatever your OS considers to be the correct exit values (typically POSIX's zero==success).

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!