C ++ bit shifter float

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? 

Print length gives: 0.0

The final result should be: 16.16;

This idea is from http://en.wikipedia.org/wiki/Fast_inverse_square_root . Im trying to understand a section of code was long in a float and bitwise operations are performed on it. I guess you need to improve performance by avoiding branching?

The above code does not work. Can someone tell me what I am doing wrong? I got the impression that it was as easy as getting the long store in the float and manipulating it, right?

I found something interesting if I changed 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.

Print length * 100 gives: 17.0538 // approximation 16.16
trying it with different lengths gives the same results.

for example: length = 100; result: 10.3299 ?? // almost ...

+6
source share
1 answer

The 32.32f binary has the value 01000010000000010100011110101110 .

After the shift: 00100001000000001010001111010111

You can see how floating point numbers are stored in Wikipedia .

sign: 0

exp: 01000010 = 66

Mantissa: +00000001010001111010111 = 2 -7 (around)

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

This is not zero. If you use printf("%.40f\n",x2); , you will see it.

If it seems strange to you why magic numbers work: you can read the wiki page or read this paper .

+13
source

Source: https://habr.com/ru/post/946460/


All Articles