June 16th, 2013, 10:11 AM

Int i=10; printf("RESULT IS %f \n",i/2) Returns 0
Hi
I just started with C and below is a code which I was expecting to see 5 but gives zero.
Code:
#include <stdio.h>
#include <stdlib.h>
void main(){
int i=10;
printf("RESULT IS %f \n",i/2);
}
RESULT IS 0.0000000
But when I cast it using the below works
Code:
printf("RESULT IS %f \n",(float)i/2);
Per my understanding, in the first case i/2 should evaluate to 5 and the same should have been implicitly converted to float. not sure what is happening.
Thanks
Zulfi
June 16th, 2013, 10:29 AM

Per my understanding, in the first case i/2 should evaluate to 5 and the same should have been implicitly converted to float. not sure what is happening.
Your understanding is incorrect. First implicit conversions don't happen with printf(), you must insure you use the proper format specifier that matches the data item.
Next even if there was an implicit conversion the calculation would still be an integer calculation, only the result of the calculation would be converted, the truncating of the calculation would still be a problem. To force a floating point calculation at least one of the terms must be a floating point value.
Jim
June 16th, 2013, 11:23 AM

Variadic functions (those with undefined type and number of parameters) such as printf() cannot "know" the type of the arguments. The programmer is responsible for ensuring correct behaviour  in the case of prinrf() by supplying a correct format specifier. Your format specifier says it is float when it is an int. The bit pattern is then incorrectly interpreted.
Implicit conversions occur only when a value or expression is assigned to a variable or argument of a different type for which a conversion exists. In the case of printf() the variadic argument has undefined type. The compiler knows nothing about format specifiers; that is used only at runtime by the implementation of printf().
In gcc the Wformat warning specifier will validate stdio format strings at compile time. Most other compilers however will not perform this check, and the check will not work on variadic functions of your own or from other libraries  even if you use the same format specifiers.
June 16th, 2013, 12:20 PM

As both jimblumberg and clifford are telling you, using the wrong format flag will cause the bit pattern of the value to be interpreted incorrectly.
I have written utilities that display the bit pattern in hex of float and double values and vice versa. Here's what they show:
C:>hex2d 00 00 00 00 00 00 00 05
Echo: 00 00 00 00 00 00 00 05
00 00 00 00 00 00 00 05 = 0.00000000000000
C:>hex2f 00 00 00 05
Echo: 00 00 00 05
00 00 00 05 = 0.000000
C:>f2hex 5
5.000000 = 40 A0 00 00
C:>
BTW, if you misinterpret 5.0f as int, then you'll get 1,084,227,584.
Now you can see what the bit patterns are and what happens when you misinterpret them.
If you want to learn more about the floatingpoint format being used, read up on IEEE 754.
June 17th, 2013, 07:32 AM

Thanks all
I worked out the bit pattern.
5 int > 00000000000000000000000000000101
When the above bit pattern is interpreted as Float.
0 00000000 00000000000000000000101
Deriving the number m * 2 ^(127+e)
The MSB would be the sign bit, 0 representing +ve sign
The next 8 bits would be the exponent (biased by 127). since 0, the exponent e should be 127.
The Significand bits (00000000000000000000101) compute to 1.0000005960464477539
Therefore the real number is
1.0000005960464477539 * 2^(127)=0.0000000000000000000000000000000000000058774752573575983518496258
but the bit sequence is being interpreted as 0.
Code:
#include <stdio.h>
#include <stdlib.h>
int main(){
int i=10;
printf("VALUE is %2.50f \n",i/2);
}
VALUE is 0.000000000000000000000000000000000000000000000000000
Please guide where I am going wrong
June 17th, 2013, 09:14 AM

Originally Posted by zulfi123786
Thanks all
dwise, I worked out the pattern and it matches what you posted. Now wondering why printf() returned 0, if it is just about reading bit patterns it should have read 1084227584.
BECAUSE YOU TOLD IT TO INTERPRET THAT AS FLOATINGPOINT!
What is wrong with these people? Why do they never listen?
June 20th, 2013, 01:30 AM

Thanks all
I worked out the bit pattern.
5 int > 00000000000000000000000000000101
When the above bit pattern is interpreted as Float.
0 00000000 00000000000000000000101
Deriving the number m * 2 ^(127+e)
The MSB would be the sign bit, 0 representing +ve sign
The next 8 bits would be the exponent (biased by 127). since 0, the exponent e should be 127.
The Significand bits (00000000000000000000101) compute to 1.0000005960464477539
Therefore the real number is
1.0000005960464477539 * 2^(127)=0.0000000000000000000000000000000000000058774752573575983518496258
but the bit sequence is being interpreted as 0.
Code:
#include <stdio.h>
#include <stdlib.h>
int main(){
int i=10;
printf("VALUE is %2.50f \n",i/2);
}
VALUE is 0.000000000000000000000000000000000000000000000000000
Please guide where I am going wrong
June 20th, 2013, 03:54 AM

Originally Posted by zulfi123786
Thanks all
I worked out the bit pattern.
5 int > 00000000000000000000000000000101
When the above bit pattern is interpreted as Float.
0 00000000 00000000000000000000101
Deriving the number m * 2 ^(127+e)
The MSB would be the sign bit, 0 representing +ve sign
The next 8 bits would be the exponent (biased by 127). since 0, the exponent e should be 127.
The Significand bits (00000000000000000000101) compute to 1.0000005960464477539
Therefore the real number is
1.0000005960464477539 * 2^(127)=0.0000000000000000000000000000000000000058774752573575983518496258
but the bit sequence is being interpreted as 0.
Code:
#include <stdio.h>
#include <stdlib.h>
int main(){
int i=10;
printf("VALUE is %2.50f \n",i/2);
}
VALUE is 0.000000000000000000000000000000000000000000000000000
Please guide where I am going wrong
%2.50f is not cast, just a pattern to write out
You must cast at 'i' ==> (float)i/2 or (float)i/2.0
:cool:
June 20th, 2013, 04:21 AM

Thank you for the reply.
My intension is to understand what is happening underneath when int bit pattern is being treated as float. An explicit cast will solve the purpose but trying to understand why it has read a zero when it was instructed to interpret the bit pattern as float. I was expecting 0.0000000000000000000000000000000000000058774752573575983518496258
which is the equivalent float value for the interger bit pattern of value 5
June 20th, 2013, 05:21 AM

Unfortunately, most compiler display float with only 8 digit of precision.
You cannot get the value you expect, even if you use %.100f.
:D
June 20th, 2013, 05:25 AM

Now my apetite is satisfied :D
June 20th, 2013, 10:49 PM

I wrote a small program like this
Code:
#include <stdio.h>
int main(){
int i = 5, j = 0;
float f1 = (float)i, f2 = 0.0000001, f3=0.00000001, f4 = 0.000000001;
printf("i=%d (float=%e) binary is :\n", i,i);
for(j = sizeof(i)*8  1; j >= 0 ; j){
printf("%c", ((i>>j)&1) + '0');
if(j%8 == 0) printf(" ");
}
printf("\n\n");
printf("f1=%.20f (%e) binary is :\n", f1,f1);
for(j = sizeof(f1)*8  1; j >= 0 ; j){
printf("%c", ((*(int*)&f1>>j)&1) + '0');
if(j%8 == 0) printf(" ");
}
printf("\n\n");
printf("f2=%.20f (%e) binary is :\n", f2,f2);
for(j = sizeof(f2)*8  1; j >= 0 ; j){
printf("%c", ((*(int*)&f2>>j)&1) + '0');
if(j%8 == 0) printf(" ");
}
printf("\n\n");
printf("f3=%.20f (%e) binary is :\n", f3,f3);
for(j = sizeof(f3)*8  1; j >= 0 ; j){
printf("%c", ((*(int*)&f3>>j)&1) + '0');
if(j%8 == 0) printf(" ");
}
printf("\n\n");
printf("f3=%.20f (%e) binary is :\n", f4,f4);
for(j = sizeof(f4)*8  1; j >= 0 ; j){
printf("%c", ((*(int*)&f4>>j)&1) + '0');
if(j%8 == 0) printf(" ");
}
printf("\n\n");
return 0;
}
With win32 gcc , I got out put
Code:
i=5 (float=1.788189e307) binary is :
00000000 00000000 00000000 00000101
f1=5.00000000000000000000 (5.000000e+000) binary is :
01000000 10100000 00000000 00000000
f2=0.00000010000000116861 (1.000000e007) binary is :
00110011 11010110 10111111 10010101
f3=0.00000000999999993923 (1.000000e008) binary is :
00110010 00101011 11001100 01110111
f3=0.00000000099999997172 (1.000000e009) binary is :
00110000 10001001 01110000 01011111
You can see how significant woks.
You can trust float only first 7 digits.