-1

Possible Duplicate:
strange output in comparision of float with float literal
Comparison of float and double variables

I have a test with double and float in C, but I cannot explain why.

    float x = 3.4F;
    if(x==3.4)
        printf("true\n");
    else printf("false\n");
    double y = 3.4;
    if (y==3.4)
        printf("true\n");
    else printf("false\n");

The result will be False and True. Please explain for me please.

Community
  • 1
  • 1
hqt
  • 29,632
  • 51
  • 171
  • 250
  • **Many** duplicates, e.g. [Comparison of float and double variables](http://stackoverflow.com/questions/3988821/comparison-of-float-and-double-variables) and [strange output in comparision of float with float literal](http://stackoverflow.com/questions/1839422/strange-output-in-comparision-of-float-with-float-literal). – Paul R Jun 26 '12 at 07:57
  • You might like this blog post: http://blog.frama-c.com/index.php?post/2011/11/08/Floating-point-quiz – Pascal Cuoq Jun 26 '12 at 10:31
  • @PascalCuoq Oh. Very very nice article :)) At first time here, downvote + close post doesn't make me sad :D I'm so impressive for his last example :D – hqt Jun 26 '12 at 16:20
  • ah.I see this blog is yours :) i see another topics, nice too ;) – hqt Jun 26 '12 at 16:22

5 Answers5

5

x == 3.4 should be x == 3.4F, otherwise the 3.4 is a double (by default). Always compare like with like, not apples and oranges.

Edit: Whether the result of the comparison between types of different precision is true or false depends on the floating point representation of the compiler.

Floating point numbers, whether single precision (float) or double, are an approximation.

cdarke
  • 42,728
  • 8
  • 80
  • 84
  • In C, `double` is used by default. This is a feature of the language and not a compiler-specific thing. – Pedro Jun 26 '12 at 08:32
  • I did not mean that double as a default was compiler specific, I meant that the comparison effect is. Sorry for the mis-understanding. – cdarke Jun 26 '12 at 08:35
  • The effect of the comparison to a floating-point constant is also defined in the standard and should not be subject to compiler-specific features... Could you edit your answer to make this clearer? – Pedro Jun 26 '12 at 08:45
  • Comparison between types of different precision does not depend on the floating-point representation of the compiler. The comparison "a == b" evaluates to true if and only if the values represented by a and b are equal. This is true even if a and b are different floating-point types, because the less precise type will be converted to the more precise type with no error. It is also incorrect to say that floating-point numbers are approximations. The values of floating-point objects are precisely specified; each represents a single, exact, completely defined number (or NaN). (Continued below.) – Eric Postpischil Jun 26 '12 at 14:28
  • It is floating-point operations that introduce errors, not floating-point objects or comparisons. When the exact mathematical result of a floating-point operation cannot be exactly represented, a rounded result is returned. Also, complex mathematical functions may be approximated, such as sine and log, so that the results they return are not always the best possible. This distinction about where errors occur is important because engineers who wish to design or prove floating-point code must use the actual properties of floating-point operations. – Eric Postpischil Jun 26 '12 at 14:30
  • There is one exception to what I wrote: It is possible to have one floating-point type with a large precision and a small exponent range and another floating-point type with a small precision and a large exponent range, and then comparisons between two values of those types could be problematic. However, this does not arise with the standard C types in common compilers. – Eric Postpischil Jun 26 '12 at 14:32
5

3.4 cannot be exactly represented as a double for the same reason that one third cannot be exactly represented as a base-10 decimal number using a finite number of digits -- the representation recurs.

So, the double literal 3.4 is actually the double value closest to 3.4. 3.4F is the float value closest to 3.4, but that's different from the closest double value.

When you compare a float with a double, the float is converted to double, which doesn't change its value.

Hence, 3.4F != 3.4, just as 0.3333 != 0.33333333

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
2

No guarantee that the result will be false and true, but the basic idea is pretty simple: 3.4 has type double. When you assign it to a float, it'll get rounded. When you compare, that rounded number will be promoted back to a double, not necessarily the same double as 3.4.

In the second case, everything's double throughout.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
0

Comparing for equality 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. Different compilers and CPU architectures store temporary results at different precisions, so results will differ depending on the details of your environment. If you do a calculation and then compare the results against some expected value it is highly unlikely that you will get exactly the result you intended.

In other words, if you do a calculation and then do this comparison: if (result == expectedResult)

then it is unlikely that the comparison will be true. If the comparison is true then it is probably unstable – tiny changes in the input values, compiler, or CPU may change the result and make the comparison be false.

Learner
  • 1,544
  • 8
  • 29
  • 55
  • 1
    Yes with one exception: as I believe, comparison of a number with itself is always true: `x= 3.4f; if(x == 3.4f) // must be true`. So, as I think, you can compare floats (so we have such operator in C), but you must do it careful. – Yury Jun 26 '12 at 07:47
  • Comparison of a literal with itself is always true (except for NaN, but that's not relevant in this case), as the compiler will generate the same approximation of the real number both times. Once you start doing math with those numbers, though, all bets are off. – cHao Jun 26 '12 at 07:59
  • 1
    Comparison of floating-point numbers is exact. This is a basic operation that is fully specified, and "a == b" evaluates to true if and only if a and b represent the same value. Problems arise with floating-point not because comparison is inexact but because many operations must round their results because the exact results are not representable. This distinction is important because engineers who wish to design or prove floating-point code must use the actual properties of floating-point operations. – Eric Postpischil Jun 26 '12 at 14:25
0

As a tip, comparing floating point numbers (float or double) with '==' is in most cases a bad programming practice, as you might never get the statement to be true. The two numbers might differ in their least significant bits.

It is better using something like:

abs(x - y) < EQUALITY_MARGIN

With EQUALITY_MARGIN being an adequately small number.

Kostas
  • 1,292
  • 1
  • 13
  • 20