Jae*_*LEE 7 c++ x86 nan reinterpret-cast
我需要保存一个浮点值,它是一个整数值的复制内存.在reinterpretedFloat函数中,我创建了一个样本整数并将内存复制到float变量.事情是变化值当的memcpy-ED浮动收益.
这是示例代码.
#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;
}
Run Code Online (Sandbox Code Playgroud)
这是结果.
0X 58 5E 84 7F(memcpy)
0X 58 5E C4 7F(returned value)
Run Code Online (Sandbox Code Playgroud)
我的期望是0X 58 5E 84 7F......
任何机构都可以解释为什么会这样?在x64配置中,这不会发生.
0x7f845e58是信令NaN.它被归一化为0x7fc45e58,这是一个具有相同有效载荷的安静NaN.
x86-64和32位x86结果之间的区别是因为在前一种模式中,float要从reinterpretedFloat()函数返回值,MOVSS来自SSE ISA扩展的指令将值加载到xmm0寄存器中而不进行任何转换,而使用后者FLD dword [...]则使用,从32位转换float为x87的内部80位long double格式,将信令状态标准化为安静*.
机制上的差异是由于x86-64体系结构保证支持SSE,因此ABI使用它,而i386 ABI不需要它,因为并非所有x86 CPU都支持它.
*从技术上讲,转换会导致无效操作异常,但由于它被屏蔽(默认情况下),因此您可以获得从NaN中删除信令状态的标准化结果