2,943 views
7 votes
7 votes

The output of the following C program will be (assume IEEE-754 floating point representation)

#include <stdio.h>
int main()
{
    float a = 0.25;
    if(a == 0.25)
        printf("Hello");
    printf(" World");
}
  1. Hello World
  2.  World
  3. Compile Error
  4. Hello

4 Answers

Best answer
21 votes
21 votes

Answer to this is A. Lets see in detail. Consider the following modified code:

#include <stdio.h>

void printbits(char a)
{
        int i;int flag = 1<<7;
        for(i=0; i< 8; i++){
                printf("%hu",(a & flag) > 0 );
                flag>>=1;
        }
        printf(" | ");
}
void printbinary(float a)
{
        int i;char *p = ((char*) &a) + sizeof a - 1;
        printf("Binary equivalent of %f is : ", a);
        for(i=sizeof(a); i >0; i--)
        {
                printbits(*p);
                p--;
        }
        printf("\n\n");
}

int main()
{
    float a = 0.25;
        printbinary(a);
    if(a == 0.25)
        printf("Hello");
    printf(" World");

        printf("\n\n");
        float b = 0.1;
        printbinary(b);
    if(b == 0.25)
        printf("Hello");
    printf(" World");
}

Here, printbinary is printing the binary representation of the float value taking one byte at a time from end. Byte is taken first from end as the code is run on a little-endian machine. The output is as follows:

Binary equivalent of 0.250000 is : 00111110 | 10000000 | 00000000 | 00000000 | 

Hello World

Binary equivalent of 0.100000 is : 00111101 | 11001100 | 11001100 | 11001101 | 

 World

Got anything? Not easy to get because for that we need to know IEEE floating point representation. Fortunately or not, that is also part of GATE syllabus. So lets see. IEEE 754 representation for float has

  • 1 sign bit
  • 8 exponent bits with a bias 127. i.e., actual exponent value needs to be subtracted by 127.
  • 23 mantissa bits

So, for 0.25 we get

  • Sign bit 0
  • Exponent bits are 01111101
  • Mantissa bits are all 0s.

So, how we get 0.25 from these bits? Just apply the IEEE 754 formula

Signbit. (1.mantissa bits) 2^(EXponent bits - bias)

1 is added before "." because if exponent is nonzero, IEEE 754 uses normalized representation.

$= 1.0 \times 2^{125 -127} = 1.0 \times 2^{-2} = 0.25$.

Same way we can do for 0.1.

But did we get the answer to the given question? Or why the output differ for both? I guess no, all the previous steps are the basics required to understand the real C part.

if(a == 0.25)

Here, 'a' is a float value and by default any decimal value is double. So, we are comparing two different operand types. But C language does implicit conversion and does promote a lower type to a higher type. i.e., here it promotes float a to a double a by padding the mantissa bits with 0's. Now, after this operation, will they both equate to 0? Yes, because the mantissa bits were already 0 and even with more precision (52 bits for double) they are still 0s. But for 0.1, this is not the case as when we concert this to a binary number we do not get an exact representation and thus with more number of bits we just increase the precision. So, padding the float value with 0's and making an actual double value makes a difference here. 

So, the real culprit is if we can represent the value exactly in binary within some (24 to be exact) bits (23 + 1 from normalized representation). If this behaviour is undesired, force float constant by using

if(a == 0.1f)
selected by
1 votes
1 votes

1st convert 0.25 into binary number, which is (0.01). i.e It's an example of fixed point representation or given a fixed length after decimal point 0.25 can be represented.

but there are some number like 0.623, for which we can't define binary of it within fixed length, from here the concept of Floating point representation has come. IEEE 754 is a floating point representation.

0.623 = 0.100110..........keep going infinitely

Now for 0.25 the float variable 'a' can express it using binary within a fixed length.

so the if part (0.01 == 0.01) will true & 'Hello' will be printed - https://onlinegdb.com/SymiqxVLB

but in case of 0.623, the float variable will not represent binary within fixed length, so it will truncate some part after decimal point which results the value of a is nearly 0.623, but not exactly 0.623. i.e if() will return false in this case - https://onlinegdb.com/BkbHseVLH

 

0 votes
0 votes
#include <stdio.h>
int main()
{
    float a = 0.25;
    if(a == 0.25)
        printf("Hello");
    printf(" World");
}

Prints Hello World.(OPTION A)


#include <stdio.h>
int main()
{
    float a = 0.777;
    if(a == 0.777)
        printf("Hello");
    printf(" World");
}

Prints World.



    float a = 0.25;

This is saved in the machine as 0.01 (binary)

If 0.01 == 0.01 — if-condition satisfied.


    float a = 0.777;

It's actual value is 0.11000110111010011... 

But IEEE 754 single precision format would approximate this value, because this value can't precisely be represented with 23 mantissa bits.

So, 0.777 is saved as something else that's approximately equal but not exactly equal to 0.777.

Which can't satisfy the if condition.


 

Answer:

Related questions

3 votes
3 votes
2 answers
2
8 votes
8 votes
2 answers
3
1 votes
1 votes
3 answers
4