c++ bit shifting a float

16,362

The binary of 32.32f is 01000010000000010100011110101110.

After shift: 00100001000000001010001111010111

You can see how float numbers is stored from Wikipedia.

sign:0

exp:01000010=66

mantissa:00000001010001111010111=2-7(around)

So the result = 2(66-127)*(1+2-7)=2-59(around)

It's not zero. If you use printf("%.40f\n",x2); then you will see it.

If you feel strange about why that magic numbers works: you can read the wiki page carefully or read this paper.

Share:
16,362
Anthony Raimondo
Author by

Anthony Raimondo

Updated on June 04, 2022

Comments

  • Anthony Raimondo
    Anthony Raimondo almost 2 years
    float length =  32.32f;
    long  i = *(long*)&length ; // casting a float pointer to a long pointer...
    i >>= 1; // right shift i but 1 ... or div by 2
    length = *(float*)&i; // is this necessary?
    

    Printing length gives: 0.0

    The end result should be: 16.16;

    This idea is from http://en.wikipedia.org/wiki/Fast_inverse_square_root. Im trying to understand the section of the code were the long in a float is taken out and bitwise operations are performed on it. Im guessing the point is to improve performance by avoiding branching?

    The above code fails. Can anyone tell me what im doing wrong? I was under the impression that it was as simple as getting the long storage in a float and manipulation it, is this wrong?

    i found something interesting, if i change the code to:

     float length =  32.32f;
     long  i = *(long*)&length ;
     i  = 0x5f3759df - ( i >> 1 ); 
     length = *(float*)&i;
    

    adding this number (0x5f3759df) to the mix.

    Printing out length*100 gives : 17.0538 // approximation of 16.16
    trying it with different length gives the same results.

    eg: length = 100; result is : 10.3299?? // almost...