为什么我用C联合获得这个输出?

时间:2017-08-25 03:46:11

标签: c output unions

#include<stdio.h>

union U{
    struct{
        int x;
        int y;
    };
    float xy;
};

int main(){
    union U u;
    u.x = 99;
    printf("xy %f\n",u.xy); //output " 0 "
    return 0;
}

我已经发现它与如何在内部存储和读取浮点数有关。有人可以向我解释一下吗?

4 个答案:

答案 0 :(得分:1)

将评论转换为答案。

使用%f打印并不是很有用;您应该考虑%g%e。使用%f时,如果值非常小,即使它不为零,也会打印为0.000000。 (例如,任何小于0.0000005的值都将打印为0.000000。)例如,您需要阅读Wikipedia上的IEEE 754,以了解如何表示此类值。

例如,在使用GCC 7.2.0运行macOS Sierra 10.12.5的Mac上,使用:

进行打印
printf("xy %22.16g\n", u.xy);

产生

 xy 1.387285479681569e-43

4字节float中的正常数字范围通常为10⁺³⁸到10-3⁸,因此来自1.387…E-43的值float是一个次正规值(尽管在8字节double值的范围。请注意,传递给float的{​​{1}}值会自动提升为printf(),因为“默认参数提升” - double实际上从未收到printf()值。< / p>

答案 1 :(得分:0)

表示float的方式会影响结果。请参阅How to represent FLOAT number in memory in Chttps://softwareengineering.stackexchange.com/questions/215065/can-anyone-explain-representation-of-float-in-memory以了解浮点在内存中的表示方式。您也没有初始化结构变量y。它可以有任何价值。它可能使用也可能不使用。在您的情况下,该值非常小,您没有打印完整的值。要查看float xy的值,您需要打印完整值。正如在这里的评论中所建议的,如果我在Windows上的Codeblocks 16.1(包含MinGW编译器)中使用以下语句,我得到的值不同于0.000000。

printf("xy %.80f\n",u.xy);

给了我     xy 0.00000000000000000000000000000000000000000013872854796815689002144922874570169700

答案 2 :(得分:0)

是的,你是对的,它与浮点值的二进制表示有关,它由Steve Hollasch在标准文档IEEE 754. See this great article中定义,以便于解释。 float是32位值,因此是int。所以在你的联合U中,xy恰好落在嵌入式结构的x成员上,因此当你将x设置为99时,位1100011(二进制表示为99)将在xy中重新解释为float的尾数。正如其他人所指出的,这是一个非常小的值,可以打印为0,具体取决于printf格式说明符。

根据你的工会成员(x,y,xy)的命名猜测,我想你想宣布一些不同的东西,例如:

union U
    {
    struct
        {
        short x;
        short y;
        };
    float xy;
    };

或者:

union U
    {
    struct
        {
        int x;
        int y;
        };
    double xy;
    };

在这些声明中,x和y成员都映射到xy成员。

答案 3 :(得分:-1)

原因是该值非常接近零,因此默认为6位数  精度不足以显示任何东西。

尝试:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h4 class="hotKeys">hot keys</h4>
<ul class="shortcut">
  <li>h</li>
  <li>p</li>
  <li>s</li>
  <li>c</li>
</ul>