浮点数转 32 和 64 位二进制表示

Posted

技术标签:

【中文标题】浮点数转 32 和 64 位二进制表示【英文标题】:Floating point number to 32 and 64bit binary representation 【发布时间】:2018-10-02 17:42:49 【问题描述】:

我需要获取一些浮点值(双精度值)的 64 位二进制表示(IEEE 754)。 我有这个用于浮点数的 32 位二进制表示的代码:

union

    float input;   // assumes sizeof(float) == sizeof(int)
    int   output;
   data;
data.input = value;
std::bitset<sizeof(float) * CHAR_BIT>   bits(data.output);

在这种情况下,联合与皈依有何关系?为什么我应该使用它? 有没有一些漂亮的方法可以做同样的事情来获得 64 位表示?

【问题讨论】:

不能以这种方式使用union。它可能会编译,但这并不能使它成为有效的代码。只有 union 中最后一个被分配的成员才有资格阅读。 const auto output = static_cast&lt;double&gt;(input) @JonathanMee 这不会保留 float 的内存表示,这是原始代码试图做的。 这不是reinterpret_cast 的用途吗? 【参考方案1】:

在这种情况下,联合与皈依有何关系?

在 C11 中,您可以使用 unions 执行“类型双关语”,这是您在此处转换的本质:将与 float 关联的位重新解释为(有符号,假定为 32-位)整数。

我为什么要使用它?

你不应该使用它。在 C++ 中,这被认为是未定义的行为,虽然许多主流编译器将支持开箱即用的基于联合的类型双关,但不能依赖它们总是提供这种行为,尤其是随着 C++ 标准在未来。

有没有一些漂亮的方法可以做同样的事情来获得 64 位表示?

如果您的编译器保证基于联合的类型双关,那么您只需将其替换为适当的 64 位整数:

static_assert(sizeof(double) == sizeof(uint64_t));
union 
    double input;
    uint64_t output;
 data;
data.input = value;
std::bitset<sizeof(double) * CHAR_BIT> bits(data.output);

如果没有,则没有漂亮方法可以做到这一点,但有一种方法可以在保证定义行为的同时做到这一点:

static_assert(sizeof(double) == sizeof(uint64_t));
uint64_t output;
double input = value;
memcpy(output, input, sizeof(double));
std::bitset<sizeof(double) * CHAR_BIT> bits(output);

【讨论】:

您可能至少要断言sizeof(double) == sizeof(std::uint64_t) 假设成立。

以上是关于浮点数转 32 和 64 位二进制表示的主要内容,如果未能解决你的问题,请参考以下文章

浮点数的十六进制表示

16进制浮点数的表示方法

浮点数的范围与精度

浮点数的范围与精度

为啥不使用基于二进制补码的浮点数?

以IEEE754短浮点数格式表示十进制数:-3.125 要求写出过程,并最终用十六进制缩写形式表示