将位间隔从变量复制到数组

Posted

技术标签:

【中文标题】将位间隔从变量复制到数组【英文标题】:Copying Bit Interval From A Variable To An Array 【发布时间】:2021-06-14 21:39:25 【问题描述】:

我有一组存储在相对较大类型的变量中的值,我必须再次将其存储在相对较小的变量中。

这里是问题的故事:我有不同类型的不同传感器值,例如 uint16_t、uint32_t 和 float。我想将值存储在 uint8_t 缓冲区数组中以通过射频发射器进行传输。对于浮点类型,我接受一个有限有效值,然后使用整数乘法将其存储在一个整数变量中。像这样:

对于这个例子,我想要逗号后面的 3 位数字,

float var1 = 12.3456789;
uint16_t var2;

var1 *= 1000;
var2 = (int) var1;

它给出了输出:

Var2: 12345 , Var1: 12345.679688

问题的总结可以如图所示,

Problem summarization

黑框是 32 字节缓冲区中的 uint8_t 类型元素,橙色框是 uint16_t 变量,我想将其分成两个 uint8_t 变量。

我尝试使用 memcpy() 作为,

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

int main() 

    uint8_t buffer[32];
    uint16_t var1 = 64000;
    
    memcpy(&buffer[0], &var1, 1);
    memcpy(&buffer[1], &var1 + 1, 1);

    printf("var1: 0x%x\n\rbuffer[0]: 0x%x\n\rbuffer[1]: 0x%x", var1, buffer[0], buffer[1]);

    return 0;

它给出了输出:

var1: 0xfa00
buffer[0]: 0x0
buffer[1]: 0x0

我曾想过使用按位运算符以某种方式分离,但失败了。如果您对此问题有任何可能的解决方案,那就太好了。

【问题讨论】:

memcpy(&amp;buffer[0], &amp;var1, 2); 呢? 一个简单的方法,从来没有这样。对,数组只是在内存中排列,将 2 个字节复制到第一个元素中即可解决。谢谢! 您可以使用按位运算符从 32 位中提取每个字节。来源bitwise 【参考方案1】:

所以,当你这样做时:

memcpy(&buffer[0], &var1, 1);
memcpy(&buffer[1], &var1 + 1, 1);

您实际上是从 &amp;var1&amp;var1 + 1 复制 1 个字节的数据。所以这里最大的问题是“&amp;var1 + 1 是什么?”。

由于var1uint16_t,因此获取地址会给您一个uint16_t*,将该指针加一将向前跳转两个字节,而不仅仅是一个。

如果您将&amp;var1 的结果转换为uint8_t

memcpy(&buffer[0], (uint8_t*)&var1, 1);
memcpy(&buffer[1], (uint8_t*)&var1 + 1, 1);

您将获得可能更接近您预期的结果:

var1: 0xfa00
buffer[0]: 0x0
buffer[1]: 0xfa

如果你想位移数据,你可以这样做:

buffer[0] = var1 & 0xFF; // mask off top 8 bits
buffer[1] = var1 >> 8; // shift top 8 bits down to bottom 8 bits

产生相同的结果...

var1: 0xfa00
buffer[0]: 0x0
buffer[1]: 0xfa

请记住,根据您的平台,如果数据源与数据使用者的表示方式不同,您可能会遇到endianness 问题。

【讨论】:

以上是关于将位间隔从变量复制到数组的主要内容,如果未能解决你的问题,请参考以下文章

从数组复制到变量导致***

SQL 编译错误:从 S3 复制到 Snowflake 时,JSON 文件格式只能生成一列类型变量或对象或数组

为啥要从方法修改变量? [复制]

js数组复制(不改变原数组)

以特定间隔循环复制粘贴

无法将局部变量复制到结果数组