#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    11
    Rep Power
    0

    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
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    159
    Rep Power
    19
    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
  4. #3
  5. Contributing User

    Join Date
    Aug 2003
    Location
    UK
    Posts
    5,109
    Rep Power
    1802
    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.
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    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 floating-point format being used, read up on IEEE 754.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    11
    Rep Power
    0
    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
  10. #6
  11. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    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 FLOATING-POINT!

    What is wrong with these people? Why do they never listen?
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    11
    Rep Power
    0
    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
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    40
    Rep Power
    19
    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:
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    11
    Rep Power
    0
    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
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    40
    Rep Power
    19
    Unfortunately, most compiler display float with only 8 digit of precision.

    You cannot get the value you expect, even if you use %.100f.

    :D
  20. #11
  21. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    11
    Rep Power
    0
    Now my apetite is satisfied :D
  22. #12
  23. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2013
    Posts
    40
    Rep Power
    19
    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 win-32 gcc , I got out put

    Code:
    i=5 (float=1.788189e-307) binary is :
    00000000 00000000 00000000 00000101 
    
    f1=5.00000000000000000000 (5.000000e+000) binary is :
    01000000 10100000 00000000 00000000 
    
    f2=0.00000010000000116861 (1.000000e-007) binary is :
    00110011 11010110 10111111 10010101 
    
    f3=0.00000000999999993923 (1.000000e-008) binary is :
    00110010 00101011 11001100 01110111 
    
    f3=0.00000000099999997172 (1.000000e-009) binary is :
    00110000 10001001 01110000 01011111
    You can see how significant woks.

    You can trust float only first 7 digits.

IMN logo majestic logo threadwatch logo seochat tools logo