1,998 views

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

if a is replaced by some other value like (0.10 , 1.1).

then Output is

 World.

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)
by

its a superb brilliant enlightening explanation. Thanx arjun sir. Thanks a lot lot lot.....lot^ infinity
0.25 is represented in system as 0.244444444444445  or 0.2500000000000001  etc . rt ?
will it take 0.25 ?   I think output will be only " World "

Correct me if wrong
edited by

@arjun sir

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

Output : Hello World

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

Output : World

My question is upto what value of a Output fluctuates ?

We need to calculate the IEEE 754 of that number and compare the bits in order to know the loops enter If or else part , rt ?

convert to binary and then see the output. it will be clear.
@Arjun Sir

why 0.1 not get exact representation?
@Srestha 0.1 is in decimal. First, we have to convert this to binary. Once you do this, you will get the reason :)
promotion is one type of type casting . There are two type of casting. By default we do upcasting. And that is why promotion is used. rt?

But I am getting

Binary equivalent of 0.100000 =000011000011..........

how it is

00111101 | 11001100 | 11001100 | 11001101 |

not getting this

Please do not see tutorial links on web - if you Google go to standard websites from Universities or Professors.

For your binary representation, why did you put "....." ? How will you represent this using 32 bits which is the size of float?

(The binary representation I used is IEEE 754)

is the information not right?

Can u refer me some standard reference?

I used "......"  because

000011

repeats every time in binary representation.

means $0.1\times 2=0.2,0.2\times 2=0.4,0.4\times 2=0.8,0.8\times 2=1.6,0.6\times 2=1.2$

and it repeats

yes IEEE u used , but how u get

00111101 |

as first 8 bit?

"it repeats" -> so how will we store this information in a fixed set of binary bits?
by normalization.rt?
No. By approximation only. Forget about IEEE representation and just do this manually using 32 bits and 64 bits. Will the answer be same? Then try to do for 0.25.
yes got it :)

Can u plz tell me what is use of this line in code?

char *p = ((char*) &a) + sizeof a - 1
how do it prints both hello world in same time?

means if and else part same time?
@arjun sir can this conclusion be made that the no. Whose binary equivalent is not exact like 0.1, 0.2 will return 0.
And no. Like .25,.5,.375,.875 will return true because their exact binary equivalents are possible.
yes. But you do not have to learn that for GATE. Because C language is not tied to IEEE 754 representation and hence this question won't be asked for GATE. I made this question mainly to test the understanding of IEEE 754 representation which is in GATE syllabus.
Got it sir

@srestha there is no else part in the question. printf("Hello") is in the if block and printf("World") is outside that block so it will run independently of the if condition.

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

by
i think option(d) is correct because a==.25

so statement is "Hello" only print
#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.