3

Consider this program

float a = 0.7f;

if (a < 0.7)
{
    Console.WriteLine("Less");
}

The output is Less. Why??

Sae1962
  • 1,122
  • 15
  • 31
NAMO
  • 263
  • 3
  • 12
  • 2
    take a look: http://stackoverflow.com/questions/618535/what-is-the-difference-between-decimal-float-and-double-in-c?rq=1 – Ric Nov 18 '13 at 14:07
  • 1
    Probably because the binary floating point representation cannot exactly represent a decimal number like 0.7 – Baldrick Nov 18 '13 at 14:07
  • 2
    the explanation is Very Long. you should read: for basic explanation: http://stackoverflow.com/questions/618535/what-is-the-difference-between-decimal-float-and-double-in-c?rq=1 for full explanation: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html – Nahum Nov 18 '13 at 14:07
  • Not sure why the downvotes though. Would not have considered it a bad question. Just a duplicate... – Baldrick Nov 18 '13 at 14:13

2 Answers2

10

Because 0.7 does not have an exact representation as a float or a double: it is not an exact sum of negative powers of 2.

It happens that the closest representation of 0.7 as a is float approximately 0.69999998807907104492, while the closest double representation is 0.69999999999999995559. As you can see, double is slightly greater, which explains the behavior of your program.

Here is a small demo that you could run to see the values on your system:

printf("%20.20f %20.20f\n", 0.7, (float)0.7);

(live demo on ideone).

The takeaway lesson here is that you should not expect double and float representations of mathematically equal numbers to compare for equality correctly. Only a small subset of fractional numbers are representable in floating point system as exact numbers.

Since the overwhelming majority of fractions would be approximated, it is a good idea to do the comparisons with some level of tolerance. For example, instead of writing if (a == 0.7) you should write if (abs(a - 0.7) < 1E-8)

Sae1962
  • 1,122
  • 15
  • 31
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
6

You're unknowingly comparing apples and potatoes in your code.

float a = 0.7f; // "0.7f" is a float
if(a< 0 .7)     // "0.7" is a double
{
    Console.WriteLine("Less"); //You'll see it because of different representations
}

Your check will work as you expect if you match the number types:

float a = 0.7f;
if(a < 0.7f)
{
    Console.WriteLine("Less"); // You won't see this
}

This is why numbers should never be hard-coded. Best way to fix your code:

float check = 0.7f;
float a = 0.7f;
if(a < check)
{ 
    Console.WriteLine("Less"); // You won't see this either
}
Alex
  • 23,004
  • 4
  • 39
  • 73