我的印象是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;
}
答案 0 :(得分:2)
在C中如何将1编码为浮点数?
有人可以帮助我理解为什么(代码失败)吗?
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。
Endian在float/uint32
答案 1 :(得分:1)
使用IEEE-754,浮点数1表示为:
0 01111111 00000000000000000000000 (base-2) = 3f80 0000 (base-16)
因此,您的假设是正确的。不幸的是,0x3f800000
表示的位模式不能仅通过以下方式分配给浮点数:
float a = 0x3f800000
十六进制数将首先转换为以10为底的值1065353216
的无符号整数。然后,该数字将隐式转换为最接近的浮点数。
因此,简而言之,虽然您的IEEE-754浮点数的位模式正确,但是您对如何分配此模式的假设却不正确。看看Convert a hexadecimal to a float and viceversa in C如何实现这一目标或该问题的其他答案。