【问题标题】:How is 1 encoded in C/C++ as a float (assuming IEEE 754 single precision representation)?1 如何在 C/C++ 中编码为浮点数(假设 IEEE 754 单精度表示)?
【发布时间】:2019-06-21 21:41:48
【问题描述】:

我的印象是 C 浮点数有 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;
}

【问题讨论】:

  • 我很确定你没有将那个位模式分配给i,而是那个特定的整数。
  • 我想弄清楚为什么你认为0011 1111 1000 0000 0000 0000 0000 0000x3F800000 应该等于1。你能解释一下这背后的思考过程吗?
  • 这不是标准的 IEEE 表示吗?见这里en.wikipedia.org/wiki/Single-precision_floating-point_format
  • 虽然我已经很多年没用过C了,但我一直认为floatdouble的具体表示取决于目标架构,而不是C标准。我的印象不正确吗?
  • @EricJ。看起来像这样。它将十六进制转换为无符号整数并将无符号整数转换为浮点数。如何直接将十六进制分配给浮点数?

标签: floating-point ieee-754


【解决方案1】:

1 如何在 C 中编码为浮点数?

谁能帮我理解为什么(代码失败)?

float i = 0x3F800000;

i = 1065353216相同;


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

在 C++ 中,建议 memcpy()

使用演员表可能会因抗锯齿而失败。 @Eric Postpischil

#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

  • float/uint32 之间的字节序不同

【讨论】:

    【解决方案2】:

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

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

    所以,你的假设是正确的。不幸的是,0x3f800000 表示的位模式不能通过以下方式分配给浮点数:

    float a = 0x3f800000
    

    十六进制数将首先转换为无符号整数,其值为1065353216,以 10 为底。然后,此数字将隐式转换为最接近的浮点数。

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

    【讨论】:

      猜你喜欢
      • 2013-07-24
      • 2021-10-06
      • 1970-01-01
      • 1970-01-01
      • 2012-01-06
      • 2014-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多