• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 523
  • Last Modified:

Checking equality of floating point numbers?

Hi,

I'm trying to check if floating point numbers are equal to one another:

    float f1  = 0.404;
    float f2  = 0.405;
    float f3  = 0.404;

    if (f1 == f2) {
        // no
    }
    if (f1 == f3) {
        // yes
    }
   
I know this comparison does not work at some point, when the number of digits past the decimal place extends "pretty far" - I'm wondering at what point on a 32 bit machine can I trust the == operator with floats? Three digits, four?

Thanks
0
DJ_AM_Juicebox
Asked:
DJ_AM_Juicebox
  • 3
  • 2
  • 2
  • +2
4 Solutions
 
jkrCommented:
The problem here is that doeble values are *never* absolutely equal, just within some margin that is called the 'machine accuracy" (epsilon or epsmach). That s where the STL class 'numeric_limits' comes in:
#include <limits>
 
using namespace std;
 
 
bool is_equal(double a, double b) {
 
  return fabs(a - b) < 2 * numeric_limits<double>::epsilon():
}

Open in new window

0
 
blahphishCommented:
Float and double values are only approximations of the numbers they are meant to represent. A float  is a 32-bit approximation, which results in at least 6 significant decimal digits, and a double is a 64-bit approximation, which results in at least 15 significant digits.

from http://www.experts-exchange.com/Programming/Languages/Java/Q_24005433.html

This is related to Java but I believe it would apply to your case.
0
 
blahphishCommented:
Found this if you're working with c# http://cplus.about.com/od/learnc/ss/variables_5.htm
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
blahphishCommented:
Sorry to spam - here for c++, meant to put this into last post.

Unless you're doing scientific programming with very large or small numbers, you'll only use doubles for greater precision. Floats are good for 6 digits of accuracy but doubles offer 15. http://cplus.about.com/od/learning1/ss/clessonone_6.htm
0
 
Kent OlsenData Warehouse Architect / DBACommented:
Hi DJ,

An IEEE 754 floating point number on a 32-bit system (the most common format and the one used by Intel and AMD) is 48 bits of mantissa and 16 bits of sign/magnitude.  One would hope that the error in a floating point computation is limited to the lowest order bit, but that's not necessarily true.  It does take a fairly unusual set of circumstances for more than the lowest couple of bits to be affected, so most applications can probably trust 45 bits of accuracy.  Note that the 45 bits represent the entire number (not just the decimal fraction) so 1,234,567,890.1 requires the same number of significant bits as .12345678901.  And 45 bits should be good for about 15 digits.

If you want to read up on the theory, Sun has a very good article here:

  http://docs.sun.com/source/806-3568/ncg_goldberg.html

Though it is probably longer, more detailed, and more boring than anyone is likely to read.  :S


Kent
0
 
DJ_AM_JuiceboxAuthor Commented:
Well I'm actually using objective-c ughh but yeah I need to compare floating points out to 3 digits, so:

    0.0 to 0.999

for equality. I was lazy and have just been doing == for the time being, all the while knowing that that is not really correct. It's just a game application and it seems to be working ok but I'd rather just patch this part up now. So what should a util function look like for this? (it will be plain C):

bool is_equal(float a, float b)
{
    return fabs(a - b) < 2 * 0.00001:
}


Thanks
0
 
jkrCommented:
You can use any margin you like therre (and can even leave out the multiplication). So, if three digits are OK for you, use
bool is_equal(float a, float b)
{
    return fabs(a - b) <  0.001:
}

Open in new window

0
 
Infinity08Commented:
It's a bit more complicated than that, since every calculation you perform with the floating point value introduces an extra error (due to rounding, inaccurate calculations, etc.), so depending on the situation, you might need to account for larger error margins.

You should keep in mind that floating point values are not precise at all, and should not be used when precision matters. Fixed point values are often a better alternative in that case.
0
 
Kent OlsenData Warehouse Architect / DBACommented:

Apologies,

I completely misstated that.  :(

A 32 bit floating point value has 23 bits of mantissa, about 7 decimal digits.  A 32 bit value has 52 bits of mantissa.  The 48 bits I mentioned earlier were a completely different architecture.

Still, only the bottom 2 or 3 bits are generally "at risk".


Kent
0
 
DJ_AM_JuiceboxAuthor Commented:
Alright great, thanks all.
0
 
Infinity08Commented:
>> I need to compare floating points out to 3 digits

If all that matters is 3 digits of precision, fixed point is a definite possibility. Depending on the range you need to cover, an unsigned long might be sufficient for your needs :
unsigned long value;
 
/* and when you want to display, you split it up : */
unsigned long after_the_comma = value % 1000;   /* 3 digits precision */
unsigned long before_the_comma = value / 1000;

Open in new window

0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 3
  • 2
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now