0

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

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

所以所有的变量都会有一个 IEEE 754 比特流,根据

浮子转换器

我遵循的步骤:

  1. 我得到 char 数组中的值
  2. 我把这些位复制到一个无符号长
  3. 在提供函数调用数据时,我将类型转换为浮点单精度。

在调试器中,我看到第 1 步和第 2 步的位模式(在缓冲区中)相同

在第 3 步中,我也看到了相同的二进制模式,但该值不被解释为浮点数

输入:21.125

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

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

结果应用程序 DataPtr * DataPtr = 1.101594624 * e9

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

4

2 回答 2

0

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

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

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

因此,假设ApplicationApimust 的声明保持不变并且void *DataPtr传递的 是将指向 a 的指针转换为指向 的指针的结果floatvoid其定义可以是:

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

关于此代码的注释:

  • 这要求它unsigned long具有float32相同的大小。
  • unsignedLong_val有文件范围是不可取的。最好将其作为参数传递。
  • 这段代码中没有任何理由认为 DataPtr 应该作为void *. 它可以作为float32 *.

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

  • 在 中组装字节的方式unsigned long可能存在字节序问题。
  • 在目前很少见的 C 实现中, anunsigned long可能具有阻止它用于保存任意字节的陷阱值。

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

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

试试这个演员:

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

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

于 2013-08-22T06:46:28.873 回答