在C中将四个字节解析为浮点
如何获取四个接收到的数据字节并将它们组合成一个浮点数 现在我将字节存储在一个数组中,它将是,接收的数据[1]收到的_数据[4]。我想将这四个字节存储为单个32位单精度浮点 -谢谢在C中将四个字节解析为浮点,c,string,parsing,floating-point,C,String,Parsing,Floating Point,如何获取四个接收到的数据字节并将它们组合成一个浮点数 现在我将字节存储在一个数组中,它将是,接收的数据[1]收到的_数据[4]。我想将这四个字节存储为单个32位单精度浮点 -谢谢 我实际上接收到一个包含19个字节的数据包,然后将两组4个字节组合成两个浮点数。因此,接收的\u数据[1]到接收的\u数据[4]是一个浮点数,接收的\u数据[5]到接收的\u数据[8]是另一个浮点数 *更新:*****更多信息… 第一位,或浮点的符号位,是第一个字节的第七位,下面是我检查的内容 #define CHECK
我实际上接收到一个包含19个字节的数据包,然后将两组4个字节组合成两个浮点数。因此,接收的\u数据[1]到接收的\u数据[4]是一个浮点数,接收的\u数据[5]到接收的\u数据[8]是另一个浮点数 *更新:*****更多信息…
第一位,或浮点的符号位,是第一个字节的第七位,下面是我检查的内容
#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))
if( CHECK_BIT(received_data[1], 7)) //set or clear LED2
{LATAbits.LATA2=1;}else{LATAbits.LATA2=0;}
if( CHECK_BIT(received_data[5], 7)) //set or clear LED3
{LATAbits.LATA3=1;}else{LATAbits.LATA3=0;}
#定义校验位(var,pos)((var)和(1),假设它们的格式已经正确:
float f = *((float*)(&received_data[1]));
请确保您的意思不是已接收\u数据[0]
。我将其保留为一个,以防您有一个填充字节。通过memcpy复制数据怎么样
inline float FloatFromByteArray (const unsigned char * received_data)
{
float f;
memcpy (&f, received_data, sizeof (float));
return f;
}
它复制从接收的_数据[0]开始的数据。如果要从接收的_数据[1]复制,只需在memcpy中添加偏移量
inline float FloatFromByteArray (const unsigned char * received_data)
{
float f;
memcpy (&f, received_data+1, sizeof (float));
return f;
}
您可以根据机器的运行顺序来组装它们,然后转换为浮点*
,并使用该指针访问它们
您通常会将它们放在数据[0]
中,数据[3]
中。因此
char *data;
//Assemble in the *right* order
data[0] = received_data[4]; // index is machine dependant!
...
// cast
float *fptr = (float *)data;
printf ("%f\n",*fptr);
从您的编辑中,也许您应该将这些内容转储到结构中
:
struct packet_s {
char byte0;
float f1;
float f2;
...
}
然后只需将(2)
或任何内容直接读入结构中即可。此方法之前已经讨论过。例如:
- 密切相关
float f1 = *(float*)(received_data+1)
float f2 = *(float*)(received_data+5)
或者,如果必须反转字节,则必须进行复制,因此这里有一个替代方案:
union {
char chars[4];
float f;
} u;
for (i = 0; i < 4; i++)
u.chars[3-i] = received_data[i+1];
float f1 = u.f;
// ... and similarly for second float
联合{
char-chars[4];
浮动f;
}u;
对于(i=0;i<4;i++)
u、 字符[3-i]=接收的_数据[i+1];
浮球f1=u.f;
//…第二个浮点数也是如此
最好是这样的情况,这些字节是由类似于此过程的相反部分写入的(或者您获取
浮点
的地址并将其强制转换为字符*
,或者您拥有字符[4]
和“float”的并集)。这就是我缓冲浮点的方式:
static char* bufferFloat (int* bLen, float value) {
*bLen = sizeof(float);
char* buf = malloc (*bLen);
int storage;
memcpy (&storage, &value, sizeof (int));
uint32_t val = htonl (storage);
memcpy (buf, &val, *bLen);
return buf;
}
这是我收到浮点数的方式:
static float readFloat (char* buf, int* bLen) {
float ret;
int temp;
if (*bLen < sizeof (float)) {
*bLen = 0;
return 0.0f;
}
memcpy (&temp, buf, sizeof (int));
uint32_t val = htonl(temp);
memcpy (&ret, &val, sizeof (float));
*bLen = sizeof (float);
return ret;
}
static float readFloat(char*buf,int*bLen){
浮网;
内部温度;
如果(*bLen
这是我写的一些业余网络代码的一部分。我希望它对我有帮助,而且对我来说似乎工作得很好。:D
实际上,如果您想要网络代码,请点击这里:/myProjects.php
然后找到正确的项目。它将被接收到\u数据[0]…接收到\u数据[3]。0-index!我实际上接收到一个包含19个字节的数据包,并将两组四个字节组合成浮点数。因此接收到的\u数据[1]到接收到的\u数据[4]是一个浮点,接收到的\u数据[5]到接收到的\u数据[9]另一个…它打破了C别名规则,可能无法处理所有的编译,可能以后会变成一个很难找到的bug。事实上,我们正在处理一个大多数系统都不存在的类型,这可能会将可移植性问题抛到窗外。严格的别名是由ISO添加的,作为不知道自己在做什么的人的支柱,我认为MNSHO.我认为没有理由浪费CPU周期去做一个memcpy(),它有着与别名应该防止的问题完全相同的问题(可能是不兼容的类型)。我更喜欢在没有严格别名的情况下运行。如果我想被当作婴儿看待,我会用VB:-)[向所有的VB程序员道歉]。这行得通吗?我以为尾数使用了一组一致的高端或低端位,等等。这不会导致数据没有正确对齐吗?@Dana:哪一个?struct dump方法确实对尾数做了一些假设…顶部的位允许您修复这个问题。不过,我忘了浮点实际上是32位ra除了更大的功能外:-\n当然,请验证union在您的平台上是否有效。我认为,这种使用是实现定义的行为,这意味着允许它在某些实现上不起作用,但他们必须这么说。如果它起作用,几乎可以肯定是正确的方法,因为它允许轻松处理字节顺序,并且不鼓励use是一个直接在线路上的结构。如果您使用指针转换路径,您可能需要验证CPU是否允许未对齐的指针。@RBerteig:我很好奇为什么它是实现定义的。您能解释一下吗?@dreamlax:在某些硬件架构上,由于对齐或其他限制,可能会出现以下情况:LUE不会直接重叠,也可能根本不会重叠。这是不太可能的,但不应该依赖它,除非知道平台允许,并且值确实重叠。我想这是可行的,但对4字节值使用memcpy()似乎是巨大的开销。malloc()也是如此:考虑到相同的数量,您可能需要重新考虑缓冲区管理。是的,如果您查看我提供的链接,我的方法可能更有意义。