将IEEE 754打包比特流转换为浮点单精度

时间:2013-08-22 06:16:53

标签: c floating-point converter ieee-754

我将unsigned long转换为Float单精度时遇到问题 这是我的问题

我需要在我的程序中以浮点进行通信,但我的所有内部变量都是无符号长的,所以我们决定的设计是这样的,所有内容都保持不变,(在unsigned long中)并且一旦需要浮点数应用程序,我将转换为浮动并传递它。

因此,根据

,所有变量都将具有IEEE 754比特流

Float converter

我遵循的步骤:

  1. 我在char数组中获取值
  2. 我拿这些位并复制成无符号长
  3. 在给出函数调用的数据时,我强制转换为浮点单精度。
  4. 在调试器中,我看到步骤1和2的相同位模式(在缓冲区中)

    在步骤3中,我看到相同的二进制模式,但该值不被解释为float

    输入:21.125

    1. 二进制:01000001101010010000000000000000
    2. 十六进制:0x41a90000
    3. 十进制:1101594624

      Code:
      void ApplicationApi(void * DataPtr)
      {
      (*(float32*)((void*)DataPtr))= unsignedLong_val;
      }
      
    4. 应用程序DataPtr的结果 * DataPtr = 1.101594624 * e9

      我在这里遗漏了什么或类型案例有效吗?

2 个答案:

答案 0 :(得分:0)

unsigned long的字节重新解释为float的标准C方法是:

y = (union { unsigned long u; float f; }) { x } .f;

此代码定义了一个复合文字,它是一个联合,它使用x的值初始化联合,该unsigned long应为f。然后它访问联合的float成员,即float。此y值已分配给float,该值应为ApplicationApi

因此,假设void *DataPtr的声明必须保持不变并且传递float是将指针转换为void指向{{1}的结果},它的定义可能是:

void ApplicationApi(void *DataPtr)
{
    * (float32 *) DataPtr =(union { unsigned long u; float32 f; }) { unsignedLong_val } .f;
}

关于此代码的说明:

  • 这要求unsigned longfloat32具有相同的尺寸。
  • unsignedLong_val不希望有文件范围。最好将其作为参数传递。
  • 此代码中没有任何理由将DataPtr作为void *传递。它可以作为float32 *传递。

关于导致此代码的代码的注释:

  • unsigned long中汇总字节的方式可能会产生字节序问题。
  • 在目前很少见的C实现中,unsigned long可能有陷阱值,无法用于保存任意字节。

关于C标准并重新解释字节:

  • 通过联合重新解释字节是C 2011(N1570)6.5.2.3 3的结果,它表示使用.运算符的表达式和成员名称具有指定成员的值。标准的注释95表示这可用于重新解释字节。
  • 另一种支持重新解释字节的方法是将指针转换为指向字符类型的指针,并使用新指针复制字节,符合6.3.2.3 7.(memcpy有时用于此。)< / LI>
  • 6.3.2.3 7仅为指向字符类型的指针定义此行为。对于其他类型,C标准通常不定义将指针转换为另一种类型的指针并取消引用结果的行为。因此,执行此操作的代码的行为是未定义的。即使它似乎在测试中工作,它也可能由于编译器优化或其他影响而失败。

答案 1 :(得分:-1)

尝试使用此演员:

void ApplicationApi(void * DataPtr)
{
  *(float32*)DataPtr = *(float32*)unsignedLong_val;
}

您必须声明正确的值是浮点值 使用您的强制转换,正确的值是一个整数,左边的值是一个浮点数。编译器将整数隐式转换为浮点值。