4
#include<stdio.h>

void main()
{
    float a = 2.3;
    if(a == 2.3) {
        pritnf("hello");
    }
    else {
        printf("hi");
    }
}

It prints "hi" in output, or we can say that if condition is getting false value.

#include<stdio.h>

void main()
{
    float a = 2.5;
    if(a == 2.5)
        printf("Hello");
    else
        printf("Hi");
}

It prints hello.

machine_1
  • 4,266
  • 2
  • 21
  • 42
Hariom
  • 75
  • 7
  • 3
    @dbush I disagree with this dupe. The supposed dupe is about floating-point *computation* being potentially inexact, while this question is about `float` versus `double` constants. The same problem would occur if `a` was a `short` or `char` that could not represent an integer constant. – EOF Sep 21 '16 at 12:26
  • So why is it happening?? – Hariom Sep 21 '16 at 12:32
  • 2
    Read http://floating-point-gui.de/ (and that URL is important enough to be remembered) – Basile Starynkevitch Sep 21 '16 at 12:35

3 Answers3

12

The variable a is a float that holds some value close to the mathematical value 2.3.

The literal 2.3 is a double that also holds some value close to the mathematical value 2.3, but because double has greater precision than float, this may be a different value from the value of a. Both float and double can only represent a finite number of values, so there are necessarily mathematical real numbers that cannot be represented exactly by either of those two types.

In the comparison a == 2.3, the left operand is promoted from float to double. This promotion is exact and preserves the value (as all promotions do), but as discussed above, that value may be a different one from that of the 2.3 literal.

To make a comparison between floats, you can use an appropriate float literal:

assert(a == 2.3f);
//             ^
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • in case of 2.5 it calculates it true?? Is it compiler specific?? – Hariom Sep 21 '16 at 12:34
  • Can you cite the part of the ISO C standard which guarantees this behavior? (I know there is one.) – Diti Sep 21 '16 at 12:34
  • 3
    Or rather ... don't use `==` for floating point values. – pmg Sep 21 '16 at 12:35
  • @Hariom: Yes, because for 2.5, both `float` and `double` happen to hold the exact same value. But that's essentially accidental. (It's because of the particular representation details of the types matching the particularly simple structure of 2.5, namely as a short, dense binary.) – Kerrek SB Sep 21 '16 at 12:35
  • I'd probably also write `float a = 2.3f;`, since this should guarantee equality. – EOF Sep 21 '16 at 12:36
  • correct but more helpful if mention that `==` is not a good idea with `floats` – Szabolcs Dombi Sep 21 '16 at 12:38
  • 1
    @pmg: I think that's overly FUDdy. You can use equality comparison if you know what it means and what you're doing. The OP's situation is blatantly solvable (e.g. with `a == 2.3f`), and I wouldn't call it bad. The important point is not to assume exact *computations*. – Kerrek SB Sep 21 '16 at 12:38
  • 1
    @DombiSzabolcs: See my previous comment. I don't agree with such an overly general statement. I prefer understanding over blind adherence to dogma. – Kerrek SB Sep 21 '16 at 12:38
  • 1
    @Diti: C11 6.2.5, "Types", says that the set of values representable by `float` is a subset of the values representable by `double`, and 6.3.1.5 on Conversions says that if a value can be represented exactly, the resulting value is that value. (C doesn't actually use the term "promotion" for floating point values, but C++ does.) – Kerrek SB Sep 21 '16 at 12:50
3

2.3 with binary representation is 01000000000100110011001100110011... so you are not able to set a float exactly to 2.3 with double precision you get something similar: 2.299999952316284

you converted a double to float when you wrote:

float a = 2.3;

the if checks if the float a is equal to double 2.299999952316284

you should write:

float a = 2.3f;

and you can check:

if (a == 2.3f) {
    ...
}

i would rather test with:

if (fabs(a - 2.3f) < 0.00001) {
    ...
}

the 2.5 represented with bits is: 01000000001000000000000000000000

EDIT: fabs is part of the <math.h> or <cmath>

Read this: article

Szabolcs Dombi
  • 5,493
  • 3
  • 39
  • 71
  • An implementation that uses decimal floats could certainly represent both 2.3 and 2.5 exactly. This is ultimately implementation-defined. The important point is that *some* values cannot be represented exactly. – Kerrek SB Sep 21 '16 at 12:52
  • no 2.3 will require infinite number of bits. C language never used decimal representation of floats, when you print the 2.3 it will show you a rounded number. – Szabolcs Dombi Sep 21 '16 at 13:05
  • 3
    @DombiSzabolcs: C11 draft standard n1570: *5.2.4.2.2 Characteristics of floating types 1 The characteristics of floating types are defined in terms of a model that describes a representation of floating-point numbers and values that provide information about an implementation’s floating-point arithmetic. 21) The following parameters are used to define the model for each floating-point type: [...] b base or radix of exponent representation (an integer > 1)* No requirement for `b` to be unequal to `10`. – EOF Sep 21 '16 at 13:11
  • interesting, i thought the values will be converted to [IEEE_floating_points](https://en.wikipedia.org/wiki/IEEE_floating_point) – Szabolcs Dombi Sep 21 '16 at 13:16
  • @DombiSzabolcs: C was developed in the very late 60's and early 70's. The IEEE 754 binary floating-point standard was established 1985. How would you expect C to require IEEE 754? – EOF Sep 21 '16 at 14:47
0

Comparing floating point values is not as easy as it might seem, have a look at Most effective way for float and double comparison.

It all boils down to the fact, that floating point numbers are not exact (well most are not). Usually you compare 2 floats by allowing a small error window (epsilon):

if( fabs(a - 2.3f) < epsion) { ... }

where epsilon is small enough for your calculation, but not too small (bigger than Machine epsilon).

Community
  • 1
  • 1
michi7x7
  • 141
  • 3