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

Posted

技术标签:

【中文标题】1 如何在 C/C++ 中编码为浮点数(假设 IEEE 754 单精度表示)?【英文标题】:How is 1 encoded in C/C++ as a float (assuming IEEE 754 single precision representation)? 【发布时间】: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。看起来像这样。它将十六进制转换为无符号整数并将无符号整数转换为浮点数。如何直接将十六进制分配给浮点数? 【参考方案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 如何实现这一点或这个问题中的其他答案。

【讨论】:

以上是关于1 如何在 C/C++ 中编码为浮点数(假设 IEEE 754 单精度表示)?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JavaScript 中将字符串转换为浮点数?

如何在python中将23位浮点数从字符串转换为浮点数并返回?

将十六进制转换为浮点数

如何在java中将4字节数组转换为浮点数

如何在 Java 中将整数转换为浮点数?

如何将 NSString 值 @"3.45" 转换为浮点数?