C函数将float转换为byte数组

Ben*_*ing 19 c floating-point casting bytearray arduino

我正在尝试创建一个接受float变量并将其转换为字节数组的函数.我找到了一段有效的代码片段,但如果可能的话,我想在函数中重用它.

我也在使用Arduino环境,但我知道它接受大多数C语言.

目前有效:

float_variable = 1.11;
byte bytes_array[4];

*((float *)bytes_array) = float_variable;
Run Code Online (Sandbox Code Playgroud)

我可以在这里更改以使此功能有效吗?

float float_test = 1.11;
byte bytes[4];

// Calling the function
float2Bytes(&bytes,float_test);

// Function
void float2Bytes(byte* bytes_temp[4],float float_variable){ 
     *(float*)bytes_temp = float_variable;  
}
Run Code Online (Sandbox Code Playgroud)

我不太熟悉指针等,但我读过(浮动)是使用铸造还是什么?

任何帮助将不胜感激!

干杯

*编辑:已解决

这是我的最终功能在Arduino中适用于任何发现此功能的人.在下面的答案中有更有效的解决方案,但我认为这是可以理解的.

功能:将输入浮点变量转换为字节数组

void float2Bytes(float val,byte* bytes_array){
  // Create union of shared memory space
  union {
    float float_variable;
    byte temp_array[4];
  } u;
  // Overite bytes of union with float variable
  u.float_variable = val;
  // Assign bytes to input array
  memcpy(bytes_array, u.temp_array, 4);
}
Run Code Online (Sandbox Code Playgroud)

调用函数

float float_example = 1.11;
byte bytes[4];

float2Bytes(float_example,&bytes[0]);
Run Code Online (Sandbox Code Playgroud)

感谢大家的帮助,我在过去的20分钟里学到了很多关于指针和参考的知识,Cheers Stack Overflow!

Flo*_*ris 22

最简单的是建立联盟:

#include <stdio.h>

int main(void) {
  int ii;
  union {
    float a;
    unsigned char bytes[4];
  } thing;

  thing.a = 1.234;
  for (ii=0; ii<4; ii++) 
    printf ("byte %d is %02x\n", ii, thing.bytes[ii]);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

byte 0 is b6
byte 1 is f3
byte 2 is 9d
byte 3 is 3f
Run Code Online (Sandbox Code Playgroud)

注意 - 无法保证字节顺序......这取决于您的机器架构.

要使您的功能正常工作,请执行以下操作:

void float2Bytes(byte bytes_temp[4],float float_variable){ 
  union {
    float a;
    unsigned char bytes[4];
  } thing;
  thing.a = float_variable;
  memcpy(bytes_temp, thing.bytes, 4);
}
Run Code Online (Sandbox Code Playgroud)

或者真正破解它:

void float2Bytes(byte bytes_temp[4],float float_variable){ 
  memcpy(bytes_temp, (unsigned char*) (&float_variable), 4);
}
Run Code Online (Sandbox Code Playgroud)

注意 - 在任何一种情况下,我都要确保将数据复制到作为输入参数给出的位置.这是至关重要的,因为你返回后不会存在局部变量(尽管你可以声明它们static,但是不要教你不良习惯.如果再次调用函数怎么办...)

  • @haccks--四个字节大小的两个数据元素的并集使这两个占用相同的物理内存 - 所以当我写入`thing.a`时,我也写入了字节数组.你会发现`&thing.a ==&thing.bytes` ... (2认同)
  • 非常感谢!我终于明白了工会的概念 (2认同)

Pat*_*ins 10

如果你的系统具有与你现在不同的字节顺序,那么这就是你想要做的事情的方法:

byte* floatToByteArray(float f) {
    byte* ret = malloc(4 * sizeof(byte));
    unsigned int asInt = *((int*)&f);

    int i;
    for (i = 0; i < 4; i++) {
        ret[i] = (asInt >> 8 * i) & 0xFF;
    }

    return ret;
}
Run Code Online (Sandbox Code Playgroud)

你可以在这里看到它:http://ideone.com/umY1bB

上述答案的问题在于它们依赖于floats 的底层表示:C不能保证最重要的字节在内存中是"第一".该标准允许底层系统实现float但感觉如此 - 因此,如果您在具有特定类型的字节顺序的系统上测试代码(内存中数字类型的字节顺序),它将根据处理器的类型停止工作你正在运行它.

这是一个非常讨厌,难以修复的bug,如果可能的话你应该避免它.

  • @TylerDurden它可以跨系统工作,因为它不会“破坏”系统正在使用的浮动概念。使用联合直接与内存中的值交互,因此取决于系统是否将最高有效字节存储在浮点的最高位字节中。使用此策略仅经历其他抽象——“int”和位移——因此无论底层系统如何排序其字节,它都将是一致的。 (2认同)
  • `&amp; 0xFF` 抓取最低有效字节,而不是内存中的第一个字节,因此它避免依赖于底层系统的字节顺序。 (2认同)

Fog*_*Day 5

我建议尝试一个"联盟".

看看这篇文章:

http://forum.arduino.cc/index.php?topic=158911.0

typedef union I2C_Packet_t{
 sensorData_t sensor;
 byte I2CPacket[sizeof(sensorData_t)];
};
Run Code Online (Sandbox Code Playgroud)

在你的情况下,像:

union {
  float float_variable;
  char bytes_array[4];
} my_union;

my_union.float_variable = 1.11;
Run Code Online (Sandbox Code Playgroud)