C函数将float转换为byte数组

时间:2014-06-25 23:30:51

标签: c casting floating-point arduino bytearray

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

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

目前有效:

float_variable = 1.11;
byte bytes_array[4];

*((float *)bytes_array) = float_variable;

我可以在此更改什么才能使此功能正常工作?

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;  
}

我对指针等不是很熟悉,但是我读到(float )正在使用强制转换器吗?

非常感谢任何帮助!

干杯

*编辑:已解决

这是我的最终功能在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);
}

调用函数

float float_example = 1.11;
byte bytes[4];

float2Bytes(float_example,&bytes[0]);

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

6 个答案:

答案 0 :(得分:21)

最容易建立一个联盟:

#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;
}

输出:

byte 0 is b6
byte 1 is f3
byte 2 is 9d
byte 3 is 3f

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

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

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);
}

或者真正破解它:

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

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

答案 1 :(得分:8)

如果您使用的系统与您现在使用的系统不同endianness,则可以使用以下方法来执行您想要的操作:

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;
}

您可以在此处看到它:http://ideone.com/umY1bB

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

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

答案 2 :(得分:5)

我建议尝试“工会”。

看看这篇文章:

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

typedef union I2C_Packet_t{
 sensorData_t sensor;
 byte I2CPacket[sizeof(sensorData_t)];
};

在您的情况下,例如:

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

my_union.float_variable = 1.11;

答案 3 :(得分:3)

另一种方式,没有工会: (假设byte = unsigned char)

void floatToByte(byte* bytes, float f){

  int length = sizeof(float);

  for(int i = 0; i < length; i++){
    bytes[i] = ((byte*)&f)[i];
  }

}

答案 4 :(得分:2)

虽然其他答案显示了如何使用union完成此操作,但您可以使用它来实现您想要的功能:

byte[] float2Bytes(float val)
{
    my_union *u = malloc(sizeof(my_union));
    u->float_variable = val;
    return u->bytes_array;
}

void float2Bytes(byte* bytes_array, float val)
{
    my_union u;
    u.float_variable = val;
    memcpy(bytes_array, u.bytes_array, 4);
}

答案 5 :(得分:1)

这似乎也有效

#include <stddef.h>
#include <stdint.h>
#include <string.h>

float fval = 1.11;
size_t siz;
siz = sizeof(float);

uint8_t ures[siz];

memcpy (&ures, &fval, siz);

然后

float utof;
memcpy (&utof, &ures, siz);

也是双重

double dval = 1.11;
siz = sizeof(double);

uint8_t ures[siz];

memcpy (&ures, &dval, siz);

然后

double utod;
memcpy (&utod, &ures, siz);
相关问题