我有一个32位无符号值,我想转换为ieee 754浮点数。
以下是我的变数:
unsigned int val = 0x3f800000;
float floatVal;
我知道我必须执行以下操作才能将uint值正确地转换为我期望的iee 754浮点值
floatVal = *((float*)&val);
任何人都可以解释为什么floatVal =(float)val不会返回相同的结果?而不是1.0 floatVal获取值1.0653532e + 009。我相信这部分是由于在这种类型转换过程中丢失了比特,而这些比特是通过指针转换保留的,但更详细的解释将非常受欢迎。
答案 0 :(得分:7)
在当前的C标准(C99,C11)中,通过联合应该type-pun,而不是取消引用类型转换指针:
#include <stdint.h>
uint32_t float_bits(const float f)
{
union {
uint32_t u;
float f;
} temp;
temp.f = f;
return temp.u;
}
大多数当前架构对float
类型使用IEEE-754 binary32格式,但不是全部。如果您的程序假定这一点,则应在文档中说明。
我个人喜欢在编译时检查它,如果我的代码无法应对,则编译失败。
大多数当前架构对整数和浮点类型使用相同的字节顺序(endianness),但不是全部。同样,如果您的程序假定这一点,它应该在文档中说明,或者在编译时检查它(例如,在同一个项目中使用单独的测试程序)。
在C中,表达式(type)variable
将变量variable
的值强制转换为type
类型。例如:
int32_t my_truncate(float value)
{
return (int32_t)value;
}
例如value == 2.125
,然后是my_truncate(value) == 2
。
类似地,将整数值转换为浮点类型,求值为最能代表原始整数值的浮点值。例如,(float)425 == 425.0f
。 (最终f
只是告诉值为float
类型。如果浮点值末尾没有f
,则其在C中的类型为double
。)
“存储表示”指的是值实际存储在内存中的方式。
投射和类型 - 投注之间的区别在于投射重新解释了值本身,但类型 - 投注重新解释了如何解释值的存储表示。
因此,将整数值转换为float类型只会产生最能代表原始整数值的float;但是将整数值(与float
的大小相同)类型化为float
意味着该整数值的存储表示被视为浮点值的存储表示,从而产生浮点值具有与原始整数值相同的存储表示。
同样在另一个方向。将浮点数类型化为无符号整数类型,将产生与原始浮点数具有相同存储表示的无符号整数(以及因此位)。这正是上面的float_bits()
示例函数所做的。
在C99及更高版本的C标准以及POSIXy C实现中,您可以使用frexpf()
函数将float
拆分为标准化分数: x ×2 n ,其中-1.0 <1。 x &lt; = -0.5f或0.5&lt; = n
是整数指数。
如果需要,可以使用它来构造二进制32可以在uint32_t
中表示的最接近值的表示。这对于float
未使用IEEE 754 binary32的体系结构非常有用。