我有一个 32 位无符号值,我想将其转换为 IEEE 754 浮点数。
这是我的变量:
unsigned int val = 0x3f800000;
float floatVal;
我知道我必须执行以下操作才能将 uint 值正确转换为我期望的 IEEE 754 浮点值 1.0
floatVal = *((float*)&val);
谁能解释为什么 floatVal = (float)val 不返回相同的结果?floatVal 的值不是 1.0.0,而是 1.0653532e+009。我相信这部分是由于在这种类型的类型转换中丢失了位,而位是通过指针转换保留的,但更详细的解释将不胜感激。
-
在当前的 C 标准(C99、C11)中,应该通过联合进行类型双关语,而不是取消引用类型转换指针:
#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 二进制 32 格式,但不是全部。如果您的程序假定这一点,则应在文档中说明。
我个人喜欢在编译时检查它,如果我的代码无法应对,编译失败。 -
大多数当前体系结构对整数和浮点类型使用相同的字节顺序(字节顺序),但不是全部。同样,如果您的程序假设了这一点,它应该在文档中说明这一点,或者在编译时检查它(例如,在同一项目中使用单独的测试程序)。
-
在 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_bits()
示例函数所做的。在 C99 和更高版本的 C 标准以及 POSIXy C 实现中,您可以使用
frexpf()
函数将float
拆分为规范化分数:x × 2n,其中 -1.0<= -0.5f 或 0.5 <=x<1; n
是整数指数。
如果需要,可以使用它来构造 binary32 可以表示的最接近值的表示,在uint32_t
中。这在不使用 IEEE 754 二进制 32 进行float
的体系结构上非常有用。