Understanding the memory content of a union

2019-06-17 01:21发布

问题:

Suppose I define a union like this:

#include <stdio.h>

int main() {
    union u {
        int i;
        float f;
    };
    union u tst;
    tst.f = 23.45;

    printf("%d\n", tst.i);

    return 0;
}

Can somebody tell me what the memory where tst is stored will look like?

I am trying to understand the output 1102813594 that this program produces.

回答1:

It depends on the implementation (compiler, OS, etc.) but you can use the debugger to actually see the memory contents if you want.

For example, in my MSVC 2008:

0x00415748  9a 99 bb 41

is the memory contents. Read from LSB on the left side (Intel, little-endian machine), this is 0x41bb999a or indeed 1102813594.

Generally, however, the integer and float are stored in the same bytes. Depending on how you access the union, you get the integer or floating point interpretation of those bytes. The size of the memory space, again, depends on the implementation, although it's usually the largest of its constituents aligned to some fixed boundary.

Why is the value such as it is in your (or mine) case? You should read about floating-point number representation for that (look up ieee 754)



回答2:

The result is depends on the compiler implementation, But for most x86 compilers, float and int will be the same size. Wikipedia has a pretty good diagram of the layout of a 32 bit float http://en.wikipedia.org/wiki/Single_precision_floating-point_format, that can help to explain 1102813594.

If you print out the int as a hex value, it will be easier to figure out.

printf("%x\n", tst.i);


回答3:

With a union, both variables are stored starting at the same memory location. A float is stored in an IEEE format (can't remember the standard number, you can look that up[edit: as pointed out by others, IEEE 754]). But, it will be a two's complement normalized (mantissa is always between 0 and 10, exponent can be anything) floating point number.

you are taking the first 4 bytes of that number (again, you can look up what bits go where in the 16 or 32 bits that a float takes up, can't remember). So it basically means nothing and it isn't useful as an int. That is, unless you know why you would want to do something like that, but usually, a float and int combo isn't very useful.

And, no, I don't think it is implementation defined. I believe that the standard dictates what format a float is in.



回答4:

In union, members will be share the same memory. so that we can get the float value as integer value.

Floating number format will be different from integer storage. so that we can understand the difference using the union.

For Ex: If I store the 12 integer value in ( 32 bits ). we can get this 12 value as floating point format.

It will stored as signed(1 bit), exponent(8 bits) and significant precision(23 bits).



回答5:

I wrote a little program that shows what happens when you preserve the bit pattern of a 32-bit float into a 32-bit integer. It gives you the exact same output you are experiencing:

#include <iostream>

int main()
{
    float f = 23.45;
    int x = *reinterpret_cast<int*>(&f);

    std::cout << x; // 1102813594
}