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 000
或0x3F800000
应该等于1。你能解释一下这背后的思考过程吗?
这不是标准的 IEEE 表示吗?见这里en.wikipedia.org/wiki/Single-precision_floating-point_format
虽然我已经很多年没用过C了,但我一直认为float
和double
的具体表示取决于目标架构,而不是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 单精度表示)?的主要内容,如果未能解决你的问题,请参考以下文章