3

在使用 reinterpret_cast 将整数转换为浮点数时,内存的内容会发生变化。

例如,

   float fDest = 0;
  __int32 nTempDest = -4808638;

  fDest = *reinterpret_cast<float*>(&nTempDest);

变量值 nTempest 的十六进制表示为“42 a0 b6 ff”,但在 reinterpret_cast 之后,fDest 的内容为“42 a0 f6 ff”。

任何人都可以回答为什么第三个字节从 b6 变为 f6。

4

2 回答 2

2

在纯 C++ 中,这实际上是未定义的行为。尽管如此,您所看到的还是有解释的。

我假设您给出的十六进制表示来自内存的字节视图。显然,您使用的是小端架构。所以我们开始的 32 位数量是 0xffb6a042,这确实是 -4808638 的二进制补码表示。

作为 IEC 60559 单精度浮点数(也是 32 位),0xffb6a042 是负数,表示 NaN。此表示中的 NaN 具有以下形式(二进制)

s1111111 1qxxxxxx xxxxxxxx xxxxxxxx

这里 s 是符号,x 是任意的,q=1 表示安静的 NaN,q=0 表示发信号的 NaN。

现在您正在使用信号 Nan,因为您将其分配给 fDest。如果浮点信号处于活动状态,这将引发浮点无效异常。默认情况下,此类异常会被简单地忽略,并且在传播时信号 NaN 值会被“静默”。

所以:在分配给 fDest 时,传播了 NaN,实现通过设置位 22 将其转换为安静的 NaN。这是您观察到的变化。

于 2013-01-25T20:20:04.173 回答
1

您的代码会产生一个Undefined Behavior(UB)
reinterpret_cast仅保证如果您从一种指针类型转换为另一种指针类型并将其转换回原始指针类型,那么您将获得原始数据。除此以外的任何东西都会产生 UB [注 1]

这是一个 UB,因为您不能依赖以下事实:

sizeof(float) == sizeof(nTempDest)

这不能保证true在所有实现上都适用,对于遵循严格别名的实现来说绝对不是这样。如果实现不是你得到的是未定义的行为。


[注1]这条规则有例外,如果你需要依赖这些角落规则,你是在波涛汹涌的水域游泳,所以要绝对确定你在做什么。

于 2013-01-25T06:30:48.467 回答