在使用reinterpret_cast将整数转换为float时,内存的内容会发生变化。
例如,
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。
答案 0 :(得分:1)
在纯C ++中,这实际上是未定义的行为。然而,对于你所看到的内容有一个解释。
我假设您提供的十六进制表示来自内存的字节视图。显然你是一个小端架构。所以我们开始的32位数量是0xffb6a042,这实际上是-4808638的二进制补码表示。
作为IEC 60559单精度浮点数(也是32位)0xffb6a042是负数,信令NaN。此表示中的NaN具有形式(二进制)
s1111111 1qxxxxxx xxxxxxxx xxxxxxxx
这里是符号,x是任意的,对于安静的NaN,q = 1,对于信令NaN,q = 0。
现在您正在使用信号Nan,因为您将其分配给fDest。如果浮点信令处于活动状态,这将引发浮点无效异常。默认情况下,这些异常被简单地忽略,并且当传播时,信号NaN值被“静默”。
所以:在分配给fDest时,NaN会被传播,实现通过设置第22位将其转换为安静的NaN。这是你观察到的变化。
答案 1 :(得分:0)
您的代码会产生未定义的行为(UB)
reinterpret_cast
仅保证如果您从一个指针类型转换为另一个指针类型并将其转换回原始指针类型,那么您将获得原始数据。除此以外的任何东西都会产生UB [注1]
这是一个UB,因为你不能依赖这样的事实:
sizeof(float) == sizeof(nTempDest)
在所有实现中都不能保证true
,对于遵循严格别名的那些实际上并非如此。如果实现不是你得到的是未定义的行为。
[注1] 这条规则有例外,如果你需要依赖这些角落规则,你就是在汹涌的水域游泳,所以要绝对确定你在做什么。