Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ bit shifting a float

Tags:

c++

bit-shift

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...

like image 774
Anthony Raimondo Avatar asked Jun 04 '13 00:06

Anthony Raimondo


People also ask

How do I bit-shift a float?

If you really want to bit-shift a float, you could use a method called fixed-point. Say you want to hold the number 1.23 (and bit-shift it later). You would store 123 in an int, and every time you accessed the variable you would divide the value by 100:

What is the meaning of shifting floats?

See this answer for more information. Shifting floats makes no sense since it's represented as the concatenation of a sign bit, an exponent and a mantissa. Since shifting operation is about shifting bits, it would imply shifting bits from mantissa to exponent and / or to sign bit.

What is bitwise shift operator in C++?

In C++, bit shift operators do what their names suggest, shifting bits. According to the program’s requirements, a bitwise shift operator shifts the binary bits left or right.

Why can't you left shift float variables?

You can't left shift float variables, because (a) your FPU generally will not have a barrel shifter exposed to you so physically cannot generate code to do that, and (b) what would it even mean? The underlying bit representation consists of multiple fields with different meanings, do you really want those bits bleeding into each other?


1 Answers

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.

like image 175
Sayakiss Avatar answered Sep 23 '22 18:09

Sayakiss