【问题标题】:how to convert double data to uint8 array and again return to double如何将双精度数据转换为 uint8 数组并再次返回双精度
【发布时间】:2018-12-30 13:06:18
【问题描述】:

我想以双精度形式获取数据,因此之后我将数据作为 uint8_t 数组发送。于是我确定了2个steps.Steps;

1-第一步:加倍到 uint8_t

#include <stdint.h>
#include <stdio.h>
#include <string.h>
void float2Bytes(double val,uint8_t* bytes_array);

int main(void) {
    double b=1690.000000;
    uint8_t message[1024];
    float2Bytes(b,&message[0]);
    int ii;
    for (ii=0; ii<8; ii++) 
        printf ("byteS %d is %02x\n", ii, message[ii]);
    return 0;
}

void float2Bytes(double val,uint8_t* bytes_array){
    // Create union of shared memory space
    union {
        double double_variable;
        uint8_t temp_array[8];
    } u;
    // Overite bytes of union with float variable
    u.double_variable = val;
    // Assign bytes to input array
    memcpy(bytes_array, u.temp_array, 8);
}

2-Second Step : uint8_t array to Double

你能在这个阶段提供建议吗?我能怎么做 ? 你能在第一阶段检查是否有错误。 ?

谢谢。

【问题讨论】:

  • 你的代码在语法上看起来是正确的(虽然不能检查 rn),如果你想要评论你应该去Code Review SE :)
  • 无论如何你为什么不能做相反的过程?复制联合中的字节并返回其double 成员
  • 您的代码是否按预期工作?
  • 附带说明:您应该将函数命名为 double2Bytes 而不是 float2Bytes
  • 第一步正在工作,但我不知道工作是否正确。我必须编写代码的第二部分以确保第一步正确与否。

标签: c casting double uint8array


【解决方案1】:

这里不需要联合。字符指针在 C 中是特殊的,可用于提取任何类型的字节表示。这意味着您当前的 main 可以被精简为:

int main(void) {
    double b=1690.000000;
    uint8_t* pmessage = (char *) &b;    // legal and portable C
    int ii;
    for (ii=0; ii<sizeof(double); ii++) // portable C
        printf ("byteS %d is %02x\n", ii, message[ii]);
    return 0;
}

从第二步开始,您需要一个memcpy 操作来从字节数组复制到不同的类型。出于完全相同的原因,这里再次不需要联合:char 指针可用于写入任何类型的字节表示:

double doubleFromBytes(uint8_t *buffer) {
    double result;
    // legal and portable C provided buffer contains a valid double representation
    memcpy(&result, buffer, sizeof(double))
    return result;
}

这里唯一的假设是buffer 指向一个包含双精度字节表示的字节数组。


当然,你在这里得到的是当前架构的双精度表示。相同的双精度值在不同的架构上可能会有所不同(*)。如果打算将表示发送到不同的机器或使用不同选项编译的程序,这可能会出现问题。

(*):至少字节顺序(字节顺序)可以不同。不是说 sizeof(double) 可能不同于 8 的奇异(无 IEC 60559 浮点)表示。

【讨论】:

  • @EricPostpischil:我的英语不够好,无法区分不必要的和无用的(我会用法语说 inutile)。编辑包括交换问题。
  • 感谢您的帮助。您的代码是我的代码的第二部分。
【解决方案2】:

您只需要一个指针即可。

int main(void)
{
    double b=1690.000000;
    // double to uint8 array
    uint8_t* pmessage = (uint8_t*) &b;
    int ii;
    for (ii=0; ii<sizeof(double); ii++)
        printf ("byteS %d is %02x\n", ii, message[ii]);

    // uint8 array to ddouble
    double c = *((double *)pmessage);
    printf ("double %f\n", c);

    return 0;
}

【讨论】:

  • 应该注意double c = *((double *)pmessage);是有效的,只是因为pmessage被分配了一个从指向double的指针转换而来的值。如果它指向一个定义为uint8_t 数组的对象,这将不是正确的代码。
  • 任何答案都应该提醒 OP 存在字节顺序和格式问题。问题提到OP想要“发送”数据。这表明他们可能正在将数据传输到另一个系统。即使其他系统对double 使用相同的格式(可能是 IEEE-754 基本 64 位二进制浮点),它也可能具有其他顺序的字节。此外,系统可以为double 使用不同的格式。
  • 从 double 转换为 uint8_t 的数据用于发送到 matlab simulink。在我再次在 matlab 中处理数据后,我发送回将 uint8_t 转换为 double 。这是我的系统。
  • @YavuzhanErdem 我已经在 C 程序和 matlab 之间发送数据,通过命名管道传递字符串。它似乎比专有的二进制协议更简单,并且是管道设置的一部分(我搞砸了),我对结果非常满意。
  • 我的代码运行良好,符合我的预期。我通过 UDP 将数据从 C 程序发送到 Matlab,所以我再次通过 udp 返回。
猜你喜欢
  • 1970-01-01
  • 2015-09-13
  • 2011-07-07
  • 2011-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-24
  • 1970-01-01
相关资源
最近更新 更多