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)