2012-08-14 66 views
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 

但是,在斯坦福大学所作的一篇演讲,杰里凯恩教授说:他确信了锅也不能为0

讲座是可喜爱here。他说在48分钟左右。

是他错了,还是说有些标准改变以来?或者平台之间是否有区别?
我使用g ++来编译我的代码。

编辑:在接下来的讲座中,他确实提到“大端”和“小尾数法”,并说,他们也影响结果。

+1

他似乎在假设大排名 – 2012-08-14 07:52:06

+2

这是UB。所以包括0在内的任何东西都可以加入 – 2012-08-14 07:52:37

+0

为什么是UB?它只是平台依赖的。其他任何事情都可以。 – innochenti 2012-08-14 07:53:52

回答

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个字节这两者都是零

注意,由于类型大小和可能的漂浮实施(不知道这一点)是实现定义不同的输出可以在不同平台上可以看出。

+0

如果您有C++ 11编译器,请使用static_assert检查类型的大小。 – Nils 2012-08-14 09:15:03

1

通过指针访问数据,以不同的类型将其存储为给出(除少数特殊情况)未定义的水煤浆。

首先,它的平台依赖于它存储的数据如何在不同的系统中提供不同的值,其次编译器很可能生成的代码甚至没有看到你期望的值,因为它可以做任何喜欢的事情当你这样做时(由于严格的别名规则,这是未定义的行为)。

话虽如此,你看到的号码有可能是有效的,但你不能依靠它,除非你明确知道你的平台会做你想做的事情,它不会被标准所保证。

2

好吧,让我们来看看。首先你写一个浮点数到内存中。它占用4个字节,值为7.内存中的浮点类似于“符号位 - >指数位 - >尾数位”。我不确定每个部件有多少位,可能取决于您的平台。

由于浮动的值是7,只占用一些右边的最低显著位(我假设大端)。

short指针指向浮动,这意味着最显著位的开始。由于该值大于0,因此符号位为零。由于float值在右边,所以我们可以说这两个最重要的字节是用零填充的。现在

,提供了一个大小的short是2,这意味着我们将只需要两个字节出浮动的4个字节,我们得到我们0

我相信,虽然,这样的结果是相当UB,可以在不同的平台,不同的编译器等

0

他“很”确定它不是零,他明确表示。

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

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