我正在尝试创建一个接受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!
答案 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);