0

以下 C++ 代码:

union float2bin{

        float f;
        int i;
    };

    float2bin obj;
    obj.f=2.243;
    cout<<obj.i;

将输出作为一些垃圾值。

union float2bin{

        float f;
        float i;
    };

    float2bin obj;
    obj.f=2.243;
    cout<<obj.i;

给出与 f 的值相同的输出,即2.243

编译器 GCC 具有相同大小的 int 和 float 即 4 但是这种输出行为背后的原因是什么?

4

2 回答 2

1

原因是浮点值以更复杂的方式存储,将 32 位划分为符号、指数和分数。如果这些位被直接读取为整数,它将看起来像一个非常不同的值。

这里重要的一点是,如果你创建一个联合,你就是说它是一个连续的内存块,可以用两种不同的方式解释。在这个机制中,它没有考虑到 float 和 int 之间的安全转换,在这种情况下会发生某种舍入。

更新:你可能想要的是

float f = 10.25f;
int i = (int)f;
// Will give you i = 10

然而,联合方法更接近于这一点:

float f = 10.25f;
int i = *((int *)&f);
// Will give you some seemingly arbitrary value
于 2013-07-21T16:55:25.513 回答
1

原因是因为它是未定义的行为。在实践中,您可以避免从大多数机器上int存储为 a 的内容中读取 a float,但除非您知道会发生什么,否则您将读取垃圾值。朝另一个方向执行可能会导致程序在int.

当然,在底层,整数值和浮点值有不同的表示,至少在大多数机器上是这样。(在某些 Unisys 大型机上,您的代码执行您期望的操作。但它们并不是最常见的系统,而且您的桌面上可能没有。)基本上,无论类型如何,您都有一系列位,它将由硬件以某种方式解释。C++ 要求整数使用纯二进制表示,这在一定程度上限制了表示。它还需要非常大的浮点值范围,并且或多或少需要某种形式的指数表示法,其中一些位表示指数,而其他位表示尾数。每个都有不同的编码。

于 2013-07-21T17:05:27.127 回答