1 如何在 C/C++ 中编码为浮点数(假设 IEEE 754 单精度表示)?

How is 1 encoded in C/C++ as a float (assuming IEEE 754 single precision representation)?

我的印象是C float有8位指数和23位尾数。

所以一个是 0011 1111 1000 0000 0000 0000 0000 0000 = 0x3F800000。

但是,以下代码生成了 1.06535e+09 而不是 1。 谁能帮我理解为什么?

#include <iostream>
#include <math.h>  

using namespace std;

int main()
{
    float i = 0x3F800000;
    cout<<i << endl;
    return 0;
}

How is 1 coded in C as a float?

Can anyone help me understand why (code fails)?

float i = 0x3F800000;

i = 1065353216相同;


在 C 中,要覆盖位模式,请使用 union 或使用 memcpy()

在 C++ 中,建议 memcpy()

由于 anti-aliasing,使用强制转换有失败的风险。

#include <stdio.h>
#include <stdint.h>

_Static_assert(sizeof(float) == sizeof(uint32_t), "Unexpected types");

int main(void) {
  union {
    uint32_t u; 
    float f;
  } x = {.u = 0x3f800000};
  float f = x.f;
  printf("%e\n", f);
  return 0;
}

在不太常见的系统上,这可能会因

而失败
  • float 不是 binary32.

  • Endian 在 float/uint32

    之间不同

使用IEEE-754,浮点数1写成:

0 01111111 00000000000000000000000 (base-2) = 3f80 0000 (base-16)

所以,你的假设是正确的。不幸的是, 0x3f800000 所代表的 bit-pattern 无法通过以下方式分配给浮点数:

float a = 0x3f800000

十六进制数将首先被转换为一个无符号整数,其值为 1065353216,以 10 为底。然后,该数字将隐式转换为最接近的 floating-point 数字。

所以简而言之,虽然您对 IEEE-754 浮点数的 bit-pattern 是正确的,但您假设如何分配此模式是不正确的。查看 Convert a hexadecimal to a float and viceversa in C 如何实现这一点或此问题中的其他答案。