从unsigned int转换为float

时间:2018-03-23 22:08:04

标签: c

我有一个32位无符号值,我想转换为ieee 754浮点数。

以下是我的变数:

unsigned int val = 0x3f800000;  
float floatVal;

我知道我必须执行以下操作才能将uint值正确地转换为我期望的iee 754浮点值

floatVal = *((float*)&val);

任何人都可以解释为什么floatVal =(float)val不会返回相同的结果?而不是1.0 floatVal获取值1.0653532e + 009。我相信这部分是由于在这种类型转换过程中丢失了比特,而这些比特是通过指针转换保留的,但更详细的解释将非常受欢迎。

1 个答案:

答案 0 :(得分:7)

  1. 在当前的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;
    }
    
  2. 大多数当前架构对float类型使用IEEE-754 binary32格式,但不是全部。如果您的程序假定这一点,则应在文档中说明。 我个人喜欢在编译时检查它,如果我的代码无法应对,则编译失败。

  3. 大多数当前架构对整数和浮点类型使用相同的字节顺序(endianness),但不是全部。同样,如果您的程序假定这一点,它应该在文档中说明,或者在编译时检查它(例如,在同一个项目中使用单独的测试程序)。

  4. 在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 。)

  5. “存储表示”指的是值实际存储在内存中的方式。

  6. 投射类型 - 投注之间的区别在于投射重新解释了值本身,但类型 - 投注重新解释了如何解释值的存储表示。

    因此,将整数值转换为float类型只会产生最能代表原始整数值的float;但是将整数值(与float的大小相同)类型化为float意味着该整数值的存储表示被视为浮点值的存储表示,从而产生浮点值具有与原始整数值相同的存储表示。

    同样在另一个方向。将浮点数类型化为无符号整数类型,将产生与原始浮点数具有相同存储表示的无符号整数(以及因此位)。这正是上面的float_bits()示例函数所做的。

  7. 在C99及更高版本的C标准以及POSIXy C实现中,您可以使用frexpf()函数将float拆分为标准化分数: x ×2 n ,其中-1.0 <1。 x &lt; = -0.5f或0.5&lt; = &lt; 1;并且n是整数指数。
    如果需要,可以使用它来构造二进制32可以在uint32_t中表示的最接近值的表示。这对于float未使用IEEE 754 binary32的体系结构非常有用。