2013-07-21 41 views
0

以下C++代码:浮到int在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 &浮动大小相同即4,但是那有什么背后的输出行为的原因是什么?

+3

即使尺寸相同,整数和浮点数的表示也是不同的......您期望看到什么? – Joel

+3

这是UB。你在哪里读到转换可以与工会完成? – Borgleader

+1

@Borgleader你确定吗?你不是通过不兼容的指针类型来混淆这种混淆吗? – 2013-07-21 16:55:47

回答

1

的原因是因为它是不确定的行为。在实践中, 在大多数计算机上,您将读取的int从 作为float存储的内容中读取,但您将阅读垃圾内容 值,除非您知道该期待什么。在其他 方向上执行此操作可能会导致程序崩溃的值为int

在引擎盖下,当然积分值和浮点数 值有不同的表示,至少在最上面的机器上是 。 (在某些Unisys主机上,您的代码做012xx您所期望的,但它们不是最常用的系统,而 您可能在桌面上没有。)基本上,无论类型如何, 你有一个位序列,这将以某种方式被硬件解释。 C++要求整数使用 整数来表示纯粹的二进制表示,这在一定程度上约束了 。它还需要非常大的浮点值范围 ,或多或少需要一些 形式的指数表示法,其中一些位代表 指数,而其他位代表尾数。使用不同的编码,每个编码为 。

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 
+0

这是C++,更喜欢'static_cast'和'reinterpret_cast'。 – Griwes

+1

你说得对。然而,在这种情况下,我认为这可能会伤害这些例子的教学价值,这就是为什么我使用C风格演员的原因。 –