联合中int成员和float成员的值是什么关系?

时间:2018-07-20 17:52:12

标签: c data-structures

#include <stdio.h>

union data {
    int a;
    float b;
};

int main()
{
    union data a1;
    a1.a=4;
    printf("%d \n%f", a1.a, a1.b);
    return 0;
}

为什么会输出4和0.000000?我希望它是4和4.0。

2 个答案:

答案 0 :(得分:3)

浮点数和整数没有相同的表示形式,因此两种字节的相同字节序列具有不同的值。

整数通常存储为位序列。因此,假设整数是4个字节,则整数值4类似于二进制中的00000000 00000000 00000000 00000100

另一方面,浮点类型的表示完全不同。大多数实现使用IEEE754格式。对于单精度浮点数(通常是float而言),第一位是符号位,接下来的8位是以2为底的指数减127,最后的23位是二进制有效数字(带有隐含的前导1)。

所以这种格式的数字4.0看起来像是二进制:

01000000 10000000 00000000 00000000

其中分为几部分:

0 10000001 00000000000000000000000

在这里,符号位为0,因此数字为正。指数字段中的值为129,转换为2。有效字段为00000000000000000000000,其中隐含前导1为1.00000000000000000000000。因此值为 + 1.0 x 2 2 ,即4。

如果您采用4的整数表示并将其解释为float,则会发生以下情况:

从4的二进制表示形式开始int

00000000 00000000 00000000 00000100

现在我们将其视为float并拆分字段:

0 00000000 00000000000000000000100

符号位为0,所以我们有一个正值。指数值0是非正规数的特殊标志。这意味着指数应理解为-126,并且有效位数具有前导0而不是前导1。因此,隐含前导0的有效值是0.00000000000000000000100。这给我们一个 + 0.000000000000000000001 x 2 -126 + 1.0 x 2 -147 的值大约是5.605194 x 10 -45 (十进制)。该值低于%f格式说明符使用的6个有效数字默认值,因此将打印0.000000。

答案 1 :(得分:0)

请记住,在一个联合中,所有成员都占用相同的存储空间-ab占据相同的字节。写入a会覆盖b,反之亦然。

intfloat的二进制表示形式非常彼此不同。假设同时使用4字节的big-endian和IEEE-754浮点格式,那么我们有

Value    Binary Representation
-----    ---------------------
    4    00000000 00000000 00000000 00000100
   4.0   01000000 10000000 00000000 00000000

我不会介绍IEEE-754格式的细节,但是基本上整数值4的二进制表示对应于一个几乎为0(至少到6个小数位)的浮点值,解释您的输出。同样,浮点值4.0的二进制表示形式对应于非常大的整数。