Consider this program:
#include <stdio.h>
union myUnion
{
int x;
long double y;
};
int main()
{
union myUnion a;
a.x = 5;
a.y = 3.2;
printf("%d\n%.2Lf", a.x, a.y);
return 0;
}
Output:
-858993459
3.20
This is fine, as the int
member gets interpreted using some of the bits of the long double
member. However, the reverse doesn't really apply:
#include <stdio.h>
union myUnion
{
int x;
long double y;
};
int main()
{
union myUnion a;
a.y = 3.2;
a.x = 5;
printf("%d\n%.2Lf", a.x, a.y);
return 0;
}
Output:
5
3.20
The question is why the long double
doesn't get reinterpreted as some garbage value (since 4 of its bytes should represent the integer)? It is not a coincidence, the program outputs 3.20 for all values of a.x
, not just 5.
However, the reverse doesn't really apply
On a little endian system (least significant byte of a multi-byte value is at the lowest address), the int
will correspond to the least significant bits of the mantissa of the long double
. You have to print that long double
with a great deal of precision to see the effect of that int
on those insignificant digits.
On a big endian system, like a Power PC box, things would be different: the int
part would line up with the most significant part of the long double
, overlapping with the sign bit, exponent and most significant mantissa bits. Thus changes in x
would have drastic effects on the observed floating-point value, even if only a few significant digits are printed. However, for small values of x
, the value appears to be zero.
On a PPC64 system, the following version of the program:
int main(void)
{
union myUnion a;
a.y = 3.2;
int i;
for (i = 0; i < 1000; i++) {
a.x = i;
printf("%d -- %.2Lf\n", a.x, a.y);
}
return 0;
}
prints nothing but
1 -- 0.0
2 -- 0.0
[...]
999 - 0.0
This is because we're creating an exponent field with all zeros, giving rise to values close to zero. However, the initial value 3.2 is completely clobbered; it doesn't just have its least significant bits ruffled.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With