将 int32 重新解释为 float
reinterpret int32 to float
我需要保存一个浮点值,它是一个整数值的复制内存。
在 reinterpretedFloat
函数中,我制作了一个样本整数并将内存复制到一个浮点变量。
问题是 当 memcpy-ed float returns.
时值会改变
这是示例代码。
#include <stdio.h>
#include <stdint.h>
void printHex(const unsigned char* buff, int count)
{
printf("0X");
for (int i = 0; i < count; ++i)
{
printf("\t%X", buff[i]);
}
printf("\n");
}
float reinterpretedFloat()
{
int32_t value = 0x7F845E58;
float tmp;
memcpy(&tmp, &value, sizeof(float));
printHex(reinterpret_cast<const unsigned char*>(&tmp), 4); //memcpy
return tmp;
}
int main()
{
float newFloat = reinterpretedFloat();
printHex(reinterpret_cast<const unsigned char*>(&newFloat), 4); //returned value
return 0;
}
这是结果。
0X 58 5E 84 7F(memcpy)
0X 58 5E C4 7F(returned value)
我的预期是 0X 58 5E 84 7F
...
任何人都可以解释为什么会这样?
在 x64 配置中,不会发生这种情况。
0x7f845e58 是 signaling NaN。它被标准化为 0x7fc45e58,这是一个具有相同负载的安静 NaN。
x86-64 和 32 位 x86 结果之间的差异是因为在前一种模式下,return 来自 reinterpretedFloat()
函数的 float
值,MOVSS
来自 SSE ISA extension loads the value into xmm0
register without any conversions, while on the latter, FLD dword [...]
is used, which converts from 32-bit float
to x87 内部 80 位 long double
格式的指令,将信号状态规范化为安静*。
机制上的差异是因为x86-64架构保证支持SSE,所以ABI使用它,而i386 ABI不需要它,因为不是所有的x86 CPU都支持它。
* 从技术上讲,转换会导致无效操作异常,但由于它被屏蔽(默认情况下),您会得到从 NaN[=19 中删除信号状态的规范化结果=]
我需要保存一个浮点值,它是一个整数值的复制内存。
在 reinterpretedFloat
函数中,我制作了一个样本整数并将内存复制到一个浮点变量。
问题是 当 memcpy-ed float returns.
这是示例代码。
#include <stdio.h>
#include <stdint.h>
void printHex(const unsigned char* buff, int count)
{
printf("0X");
for (int i = 0; i < count; ++i)
{
printf("\t%X", buff[i]);
}
printf("\n");
}
float reinterpretedFloat()
{
int32_t value = 0x7F845E58;
float tmp;
memcpy(&tmp, &value, sizeof(float));
printHex(reinterpret_cast<const unsigned char*>(&tmp), 4); //memcpy
return tmp;
}
int main()
{
float newFloat = reinterpretedFloat();
printHex(reinterpret_cast<const unsigned char*>(&newFloat), 4); //returned value
return 0;
}
这是结果。
0X 58 5E 84 7F(memcpy)
0X 58 5E C4 7F(returned value)
我的预期是 0X 58 5E 84 7F
...
任何人都可以解释为什么会这样? 在 x64 配置中,不会发生这种情况。
0x7f845e58 是 signaling NaN。它被标准化为 0x7fc45e58,这是一个具有相同负载的安静 NaN。
x86-64 和 32 位 x86 结果之间的差异是因为在前一种模式下,return 来自 reinterpretedFloat()
函数的 float
值,MOVSS
来自 SSE ISA extension loads the value into xmm0
register without any conversions, while on the latter, FLD dword [...]
is used, which converts from 32-bit float
to x87 内部 80 位 long double
格式的指令,将信号状态规范化为安静*。
机制上的差异是因为x86-64架构保证支持SSE,所以ABI使用它,而i386 ABI不需要它,因为不是所有的x86 CPU都支持它。
* 从技术上讲,转换会导致无效操作异常,但由于它被屏蔽(默认情况下),您会得到从 NaN[=19 中删除信号状态的规范化结果=]