C函数将float转换为byte数组
我正在尝试创建一个接受float变量并将其转换为字节数组的函数。 我发现了一段可行的代码,但如果可能的话,我希望在函数中重用它。
我也在使用Arduino环境,但我知道它接受大多数C语言。
目前有效:
float_variable = 1.11; byte bytes_array[4]; *((float *)bytes_array) = float_variable;
我可以在这里更改以使此function有效吗?
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; }
我对指针等不太熟悉,但我读过(浮动 )是使用铸造还是什么?
任何帮助将不胜感激!
干杯
*编辑:已解决
这是我的最终function在Arduino中适用于任何发现此function的人。 在下面的答案中有更有效的解决方案,但我认为这是可以理解的。
function:将输入浮点变量转换为字节数组
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分钟里学到了很多关于指针和参考的知识,Cheers Stack Overflow!
最简单的是建立联盟:
#include 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
注意 - 不保证字节顺序......这取决于您的机器架构。
要使您的function正常工作,请执行以下操作:
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
,但是不要教你不良习惯。如果再次调用函数怎么办...)
如果你的系统具有与你现在不同的字节顺序 ,那么这就是你想要做的事情的方法:
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
但感觉就像 – 所以如果你在具有特定类型的字节顺序的系统上测试你的代码(内存中数字类型的字节顺序),它将停止工作, 具体取决于处理器你正在运行它 。
这是一个非常讨厌,难以修复的bug,如果可能的话你应该避免它。
我建议尝试一个“联盟”。
看看这篇文章:
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;
换句话说,没有工会:(假设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]; } }
虽然其他答案显示了如何使用union完成此操作,但您可以使用它来实现您想要的function:
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); }
这似乎也有效
#include #include #include 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);