bluefalcon
bluefalcon

Reputation: 4245

What kind of conversion is this code doing?

I ran across this code, where they are trying to convert from float to int

int val[5];
union {
    int i;
    float f;
} conv;

... 
val is updated with some value
...
case OUT_FORMAT_FLOAT:
for (i = 0; i < count; i++) {
   conv.f = val[i];
   val[i] = conv.i;
}

But I am just not able to understand how this would work. The val[i] is assigned to conv.f and then the conv.i is used store back the value into val[i]. conv is a union type since we are using f, i will not have a valid value right?

Am I missing something here?

Upvotes: 8

Views: 85

Answers (2)

Some programmer dude
Some programmer dude

Reputation: 409166

It's doing something called type punning.

The thing to remember here is that floating point values are often stored in a very different format than integers (most commonly IEEE floating point format), and the use of the union is to get the raw floating point format.

To be more specific, this is what happens:

  1. The assignment conv.f = val[i]. This converts the integer in val[i] to a floating point value, and stores it in conv.f.
  2. The assignment val[i] = conv.i. This gets the raw floating-point bit-pattern stored in the union, and assigns it to val[i].

This works because a union is not like a structure with separate members. In a union all members share the same memory. Modifying one member of the union will modify all members.


A note on why a union is used: This conversion could be made in other ways as well, but then that would break the strict aliasing rule, however using unions for type punning is allowed.

Upvotes: 5

haccks
haccks

Reputation: 106012

union allows different data types to be stored at the same location. Space is allocated only for the member having sizeof(member) maximum.

Once member f is initialized, i can be accessed from that location.

Upvotes: 0

Related Questions