c++ - 将 int32 重新解释为 float

标签 c++ x86 nan reinterpret-cast

我需要保存一个浮点值,它是一个整数值的复制内存。 在 reinterpretedFloat 函数中,我制作了一个样本整数并将内存复制到一个浮点变量。 问题是当 memcpy-ed float 返回时值会改变

这是示例代码。

#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 结果之间的区别是因为在前一种模式下,要从 reinterpretedFloat() 函数返回 float 值, SSE 中的 MOVSS 指令ISA 扩展将值加载到 xmm0 寄存器而不进行任何转换,而在后者上,使用 FLD dword [...],它从 32 位 float x87的内部 80 位 long double 格式,将信号状态规范化为 quiet*。

机制上的差异是由于 x86-64 架构保证支持 SSE,因此 ABI 使用它,而 i386 ABI 不需要它,因为并非所有 x86 CPU 都支持它。

* 从技术上讲,转换会导致无效操作异常,但由于它被屏蔽(默认情况下),您会得到从 NaN 中删除信号状态的规范化结果

关于c++ - 将 int32 重新解释为 float,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50570212/

相关文章:

c++ - USB-HID 读/写(重叠)WaitForSingleObject 不返回 C++

c - 将 ebp/esp 与 edi/esi 结合使用

assembly - "iterations"中的 "perf report -b --branch-history"是什么意思(perf record -b -g)

c++ - 计算匹配数

c++ - 从另一个 C++ 中删除 1 个列表中出现的所有元素

c++ - 如何将 Unicode 字符串连接成字符串以传递给 mysql 调用

c - strcat 溢出?

c++ - NaN 在不同的 g++ 版本中处理不同

Python:Pandas Dataframe 如果 ColA 为空且 ColB 包含字符串,则新列显示字符串

c++ - C/C++中的NaN比较规则