C语言 C函数将浮点数转换为字节数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24420246/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C Function to Convert float to byte array
提问by Ben Winding
I'm trying to make a function that will accept a float variable and convert it into a byte array. I found a snippet of code that works, but would like to reuse it in a function if possible.
我正在尝试制作一个接受浮点变量并将其转换为字节数组的函数。我找到了一段有效的代码,但如果可能的话,我想在函数中重用它。
I'm also working with the Arduino environment, but I understand that it accepts most C language.
我也在使用 Arduino 环境,但我知道它接受大多数 C 语言。
Currently works:
目前工作:
float_variable = 1.11;
byte bytes_array[4];
*((float *)bytes_array) = float_variable;
What can I change here to make this function work?
我可以在这里更改什么才能使此功能正常工作?
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;
}
I'm not so familiar with pointers and such, but I read that (float) is using casting or something?
我对指针等不太熟悉,但我读到(float) 正在使用强制转换之类的?
Any help would be greatly appreciated!
任何帮助将不胜感激!
Cheers
干杯
*EDIT: SOLVED
*编辑:已解决
Here's my final function that works in Arduino for anyone who finds this. There are more efficient solutions in the answers below, however I think this is okay to understand.
这是我在 Arduino 中为找到此功能的任何人提供的最后一个功能。下面的答案中有更有效的解决方案,但我认为这很好理解。
Function: converts input float variable to byte array
功能:将输入的浮点变量转换为字节数组
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);
}
Calling the function
调用函数
float float_example = 1.11;
byte bytes[4];
float2Bytes(float_example,&bytes[0]);
Thanks for everyone's help, I've learnt so much about pointers and referencing in the past 20 minutes, Cheers Stack Overflow!
感谢大家的帮助,在过去的 20 分钟里我学到了很多关于指针和引用的知识,Cheers Stack Overflow!
回答by Floris
Easiest is to make a union:
最简单的方法是建立联合:
#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;
}
Output:
输出:
byte 0 is b6
byte 1 is f3
byte 2 is 9d
byte 3 is 3f
Note - there is no guarantee about the byte order… it depends on your machine architecture.
注意 - 无法保证字节顺序……这取决于您的机器架构。
To get your function to work, do this:
要使您的功能正常工作,请执行以下操作:
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);
}
Or to really hack it:
或者真正破解它:
void float2Bytes(byte bytes_temp[4],float float_variable){
memcpy(bytes_temp, (unsigned char*) (&float_variable), 4);
}
Note - in either case I make sure to copy the data to the location given as the input parameter. This is crucial, as local variables will not exist after you return (although you could declare them static, but let's not teach you bad habits. What if the function gets called again…)
注意 - 在任何一种情况下,我都确保将数据复制到作为输入参数给出的位置。这很关键,因为返回后局部变量将不存在(虽然你可以声明它们static,但我们不要教你坏习惯。如果再次调用函数怎么办......)
回答by Patrick Collins
Here's a way to do what you want that won't break if you're on a system with a different endiannessfrom the one you're on now:
如果您使用的系统的字节顺序与您现在所在的系统不同,这里有一种方法可以做您想做的事情,该方法不会中断:
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;
}
You can see it in action here: http://ideone.com/umY1bB
你可以在这里看到它的实际效果:http: //ideone.com/umY1bB
The issue with the above answers is that they rely on the underlying representation of floats: C makes no guarantee that the most significant byte will be "first" in memory. The standard allows the underlying system to implement floats however it feels like -- so if you test your code on a system with a particular kind of endianness (byte order for numeric types in memory), it will stop working depending on the kind of processor you're running it on.
上述答案的问题在于它们依赖于floats的底层表示:C 不保证最高有效字节在内存中将是“第一个”。该标准允许底层系统实现floats ,但感觉就像 - 因此,如果您在具有特定字节序(内存中数字类型的字节顺序)的系统上测试代码,它将停止工作,具体取决于处理器的类型你正在运行它。
That's a really nasty, hard-to-fix bug and you should avoid it if at all possible.
这是一个非常讨厌、难以修复的错误,您应该尽可能避免它。
回答by FoggyDay
I would recommend trying a "union".
我建议尝试“联合”。
Look at this post:
看看这个帖子:
http://forum.arduino.cc/index.php?topic=158911.0
http://forum.arduino.cc/index.php?topic=158911.0
typedef union I2C_Packet_t{
sensorData_t sensor;
byte I2CPacket[sizeof(sensorData_t)];
};
In your case, something like:
在您的情况下,类似于:
union {
float float_variable;
char bytes_array[4];
} my_union;
my_union.float_variable = 1.11;
回答by Christopher Schneider
Yet another way, without unions: (Assuming byte = unsigned char)
另一种方式,没有联合:(假设字节 = unsigned char)
void floatToByte(byte* bytes, float f){
int length = sizeof(float);
for(int i = 0; i < length; i++){
bytes[i] = ((byte*)&f)[i];
}
}
回答by Enzo Guerra
this seems to work also
这似乎也有效
#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);
then
然后
float utof;
memcpy (&utof, &ures, siz);
also for double
也为双
double dval = 1.11;
siz = sizeof(double);
uint8_t ures[siz];
memcpy (&ures, &dval, siz);
then
然后
double utod;
memcpy (&utod, &ures, siz);
回答by mclaassen
Although the other answers show how to accomplish this using a union, you can use this to implement the function you want like this:
尽管其他答案显示了如何使用联合来完成此操作,但您可以使用它来实现您想要的功能,如下所示:
byte[] float2Bytes(float val)
{
my_union *u = malloc(sizeof(my_union));
u->float_variable = val;
return u->bytes_array;
}
or
或者
void float2Bytes(byte* bytes_array, float val)
{
my_union u;
u.float_variable = val;
memcpy(bytes_array, u.bytes_array, 4);
}

