3

I found the following code which calculates log2 of float x:

union { float f; unsigned int i; } vx = { x };
float y = vx.i;
y *= 1.0 / (1 << 23);
y = y - 126.94269504f;
return y;

The f parameter of union is initialized to input x and then it uses i? I can not understand how it uses something that is not initialized. And what vx.i value is actually? Thank you.

alk
  • 69,737
  • 10
  • 105
  • 255
NewUser
  • 88
  • 4

4 Answers4

5

I can not understand how it uses something that is not initialized.

Actually vx.i is initialized. A union will occupy the same memory location. Therefore vx.i is initialized at the same time that vx.f is initialized.

And what vx.i value is actually?

To get the actual value of vx.i you need to understand how a float is stored in memory. Refer the excellent answer here How are floating point numbers are stored in memory?

From the answer linked,

If vx.f is 1.0 then vx.i will be 3f800000 (in hex)

Rishikesh Raje
  • 8,556
  • 2
  • 16
  • 31
3

Unions is something that comes from the time when memory was expensive. They are used to save memory.

When you declare a union, it will be large enough to hold the biggest member. So in this case, the size of vx will be max(sizeof(f), sizeof(i)).

So when you use vx = {x}, the value of x will be put in the memory that has been reserved for vx. When you are using vx.f, then whatever is in that memory will be interpreted as a float, but when you are using vx.i will instead be interpreted as an unsigned integer, but the raw binary data is the same.

klutt
  • 30,332
  • 17
  • 55
  • 95
  • 1
    Thank you very much for the clear explanation. There is actually a problem which to accept. I will upvote 2 and accept the last. – NewUser Oct 03 '18 at 11:15
  • 1
    @NewUser: Thank you! Regarding unions, there is a fine question which has all kinds of neat tricks in the answers section, that are union related: https://stackoverflow.com/questions/4788965/when-would-anyone-use-a-union-is-it-a-remnant-from-the-c-only-days – teroi Oct 03 '18 at 11:18
3

union keyword basically means that float f and unsigned int i share the same memory. initializing the union member f and then reading i is basically implementation defined.

What happens is that you get the binary representation of the float variable. The clever coder then uses that binary representation and scales the value so that you get log2 of the input value.

teroi
  • 1,087
  • 10
  • 19
  • 1
    Thank you very much for the clear explanation. There is actually a problem which to accept. I will upvote 2 and accept the last. – NewUser Oct 03 '18 at 11:15
2

Your float and int share the same memory location. So the bytes occupied by the float are the same as the bytes of the int. But they mean something completelly different as the binary format of float is different than the int. So of you assign the float value it will change the int but the meaning of it will be completely different.

0___________
  • 60,014
  • 4
  • 34
  • 74