3

我在 C++ 中运行这段代码:

#include <iostream>
using namespace std;
int main()
{
    float f = 7.0;
    short s = *(short *)&f;
    cout << sizeof(float) << endl
         << sizeof(short) << endl
         << s << endl;
    return 0;
}

我得到以下出锅:

4
2
0

但是,在斯坦福大学的一次演讲中,Jerry Cain 教授说他确信底池不会是 0。

讲座会很喜欢这里。他说,大约 48 分钟。

他是错的,还是从那以后发生了一些标准变化?还是平台之间有区别?
我正在使用 g++ 编译我的代码。

编辑:在下一次讲座中,他确实提到了“大端”和“小端”,并说它们会很好地影响结果。

4

4 回答 4

4
static void bitPrint(float f)
{
    assert(sizeof(int) == sizeof(float));
    int *data = reinterpret_cast<int*>(&f);
    for (int i = 0; i < sizeof(int) * 8; ++i)
    {
        int bit = (1 << i) & *data;
        if (bit) bit = 1;
        cout << bit;
    }
    cout << endl;
}

int main()
{
    float f = 7.0;
    bitPrint(f);
    return 0;
}

该程序打印00000000000000000000011100000010

由于sizeof(short) == 2在您的平台上,您会得到前 2 个字节,它们都是零

请注意,由于类型的大小和可能的浮点实现(不确定)是实现定义的,因此可以在不同的平台上看到不同的输出。

于 2012-08-14T07:51:39.047 回答
2

走着瞧。首先,您将浮点数写入内存。它占用 4 个字节,其值为 7。内存中的浮点数看起来像“符号位 -> 指数位 -> 尾数位”。我不确定每个部分到底有多少位,这可能取决于您的平台。

由于浮点数的值为 7,它只占用右侧的一些最低有效位(我假设为大端)。

您的short指针指向浮点数的开头,这意味着最高有效位。由于该值大于 0,因此符号位为零。由于浮点值在最右边,我们可以说这两个最重要的字节用零填充。

现在,假设大小short为 2,这意味着我们将只从 float 的 4 个字节中取出两个字节,我们得到我们的0.

不过我相信,这个结果相当 UB,并且在不同的平台、编译器等上可能会有所不同。

于 2012-08-14T07:50:56.157 回答
1

通过指向与存储为不同类型的指针访问数据会给出(除了少数特殊情况)未定义的行为。

首先,它取决于平台,它存储的数据如何存储,因此不同的系统可能会给出不同的值,其次,编译器可能会生成甚至看不到您期望的值的代码,因为当您这样做时,它可以做任何它喜欢的事情(由于严格的别名规则,这是未定义的行为)。

话虽如此,您看到的数字可能是有效的,但您不能依赖它,除非您明确知道您的平台会按照您的预期行事,这不受标准的保证。

于 2012-08-14T07:50:24.600 回答
0

他“非常”确定它不为零,他明确地说。

但是,考虑到短的表示可以是大端或小端,我不会那么肯定。无论如何,这是五十分钟演讲结束时的一句台词,所以我们可以原谅他一点。可能是他在下一次讲座中回来澄清。

您需要(至少)逐字节检查底层位以了解发生了什么。

于 2012-08-14T07:53:04.007 回答