0
float a;
a=8.3;
if(a==8.3)
printf("1");
else
printf("2");

giving a as 8.3 and 8.4 respectively and comparing with 8.3 and 8.4 correspondingly , output becomes 2 but when comparing with 8.5 output is 1. I found that it is related to concept of recurring binary which takes 8 bytes. I want to know how to find which number is recurring binary. kindly give some input.

Rakesh_Kumar
  • 1,442
  • 1
  • 14
  • 30
  • 1
    My two cents: don't use ever boolean equal operator for floats or double numbers: even mathematically equal values can be different due to machine finite precision. Always consider some tolerance if you need these operations. – Jepessen Oct 25 '13 at 13:17
  • 1
    Apparently, `(double)8.3` is not exactly representable in `float` type. – zch Oct 25 '13 at 13:18
  • http://stackoverflow.com/questions/10334688/how-dangerous-is-it-to-compare-floating-point-values/10335601#10335601 – R.. GitHub STOP HELPING ICE Oct 25 '13 at 13:36
  • Please read a FAQ, any FAQ, about float numbers... – Lundin Oct 25 '13 at 13:49

3 Answers3

3

Recurring numbers are not representable, hence floating point comparison will not work.

Floating point math is not exact. Simple values like 0.2 cannot be precisely represented using binary floating point numbers, and the limited precision of floating point numbers means that slight changes in the order of operations can change the result. Also as in the 2nd comment - floating point literals 8.3 has type double and a has type float.

Comparing with epsilon – absolute error

Since floating point calculations involve a bit of uncertainty we can try to allow for this by seeing if two numbers are ‘close’ to each other. If you decide – based on error analysis, testing, or a wild guess – that the result should always be within 0.00001 of the expected result then you can change your comparison to this:

if (fabs(result - expectedResult) < 0.00001)

For example, 3/7 is a repeating binary fraction, its computed value in double precision is different from its stored value in single precision. Thus the comparison 3/7 with its stored computed value fails.

For more please read - What Every Computer Scientist Should Know About Floating-Point Arithmetic

Sadique
  • 22,572
  • 7
  • 65
  • 91
  • 2
    In order to be precise, all binary fractions which have some other factor than 2 in the denominator are repeating. (So are all decimal fractions which don't have only 2s or 5s in the denominator: 1/3, 1/7, 1/11 are repeating; 1/2, 1/5, 1/20, 1/25 aren't. In decimal.) In binary, 0.0625 can be expressed in a finite way (as it is 1/16), 0.06 cannot (as it is 3/50, and 50=2*5*5). – glglgl Oct 25 '13 at 13:32
  • @glglgl Nice observation. :) – Sadique Oct 25 '13 at 13:34
1

You should not compare floating point numbers for equality using ==. Because of how floating point numbers are actually stored in memory it will give inaccurate results.

Use something like this to determine if your number a is close enough to the desired value:

if(fabs(a-8.3) < 0.0000005))
digital_revenant
  • 3,274
  • 1
  • 15
  • 24
  • 1
    Please avoid the cargo-cult answers. How to compare inexact results, and how to compare floating point values, are two different topics, both of which are much more complex than a single one-size-fits-all epsilon hack can solve. – R.. GitHub STOP HELPING ICE Oct 25 '13 at 13:35
0

There are two problems here.

First is that floating point literals like 8.3 have type double, while a has type float. Doubles and floats store values to different precisions, and for values that don't have an exact floating point representation (such as 8.3), the stored values are slightly different. Thus, the comparison fails.

You could fix this by writing the comparison as a==8.3f; the f suffix forces the literal to be a float instead of a double.

However, it's bad juju to compare floating point values directly; again, most values cannot be represented exactly, but only to an approximation. If a were the result of an expression involving multiple floating-point calcuations, it may not be equivalent to 8.3f. Ideally, you should look at the difference between the two values, and if it's less than some threshold, then they are effectively equivalent:

if ( fabs( a - 8.3f) < EPSILON ) 
{
   // a is "equal enough" to 8.3
}

The exact value of EPSILON depends on a number of factors, not least of which is the magnitude of the values being compared. You only have so many digits of precision, so if the values you're trying to compare are greater than 999999.0, then you can't test for differences within 0.000001 of each other.

John Bode
  • 119,563
  • 19
  • 122
  • 198