OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2700|回复: 13

如何实现几个字节同事偏移N位(按bit位偏移)?

[复制链接]

8

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2018-12-12
在线时间
16 小时
发表于 2018-12-21 17:02:02 | 显示全部楼层 |阅读模式
比如有一个三个元素的数组,转换成二进制 内容如下  00001111 00001111 00001111  ,让他们同时往左偏移3个bit位  变成 00000001 11100001 11100001  如何用C语言来实现呢?越简短越好谢谢各位网友


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

17

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
168
金钱
168
注册时间
2017-8-5
在线时间
36 小时
发表于 2018-12-21 18:27:05 | 显示全部楼层
int main() {
        int a[3] = { 0x0f,0x0f,0x0f }, b[3] = {0,0,0};
        int t = 0,tt;
        t |= a[0] << 16;
        t |= a[1] << 8;
        t |= a[2];
        t = t >> 3;
        tt = t;
        printf("0x%x\n",t);
        b[0] |= t >> 16;

        tt &= 0xff00;

        b[1] |= tt >> 8;

        t &= 0xff;
        b[2] |= t;
        for (int j = 0; j < 3; j++)
        {
                printf("b[%d]=0x%x\n",j,b[j]);
        }
}
回复 支持 反对

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2018-12-21 19:11:26 | 显示全部楼层
定一个u32 移位?
回复 支持 反对

使用道具 举报

8

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2018-12-12
在线时间
16 小时
 楼主| 发表于 2018-12-22 09:23:12 | 显示全部楼层

是吧几个数据与了然后偏移吗?可是这样的话如果我超过4byte了 就不止32位了
回复 支持 反对

使用道具 举报

8

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2018-12-12
在线时间
16 小时
 楼主| 发表于 2018-12-22 09:29:55 | 显示全部楼层
Jasonlearning 发表于 2018-12-21 18:27
int main() {
        int a[3] = { 0x0f,0x0f,0x0f }, b[3] = {0,0,0};
        int t = 0,tt;

非常感谢,你的意思是把数据与了然后再偏移吗,但是如果这个数据时为知长度的这样一个int型可能会装不下这么多
回复 支持 反对

使用道具 举报

29

主题

338

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1181
金钱
1181
注册时间
2018-4-13
在线时间
170 小时
发表于 2018-12-22 10:50:54 | 显示全部楼层
本帖最后由 xiatianyun 于 2018-12-22 10:59 编辑

如果元素个数是三个,问题比较简单,可如果个数未知就只能单个右移了。
对以,你要求左移,怎么你右移了呢?

#include <stdio.h>

int main(void)
{
    unsigned char a[3] = {0x0f,0x0f,0x0f};
    unsigned int* p = (unsigned int*)a;
    *p = (*p) >> 3;
   
    printf("右移三位是:%d\r\n", *p);
}

回复 支持 反对

使用道具 举报

2

主题

123

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1472
金钱
1472
注册时间
2014-4-8
在线时间
172 小时
发表于 2018-12-22 11:14:39 | 显示全部楼层
"往左偏移3个bit位  变成 00000001 11100001 11100001"这是右偏移
回复 支持 反对

使用道具 举报

8

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2018-12-12
在线时间
16 小时
 楼主| 发表于 2018-12-22 11:20:23 | 显示全部楼层
xiatianyun 发表于 2018-12-22 10:50
如果元素个数是三个,问题比较简单,可如果个数未知就只能单个右移了。
对以,你要求左移,怎么你右移了呢 ...

抱歉抱歉是我写错了
回复 支持 反对

使用道具 举报

8

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2018-12-12
在线时间
16 小时
 楼主| 发表于 2018-12-22 11:24:52 | 显示全部楼层
static void data_offset(uint8_t len, uint8_t data_len, uint8_t* data)
{
        uint8_t byte_nums = (data_len + 7) / 8;
        uint8_t index = byte_nums;

        data[index] = data[index - 1] << (8-len)|data[index] >> len;
        for (; index > 0; index--)
        {
                if (index == 1)
                {
                        data[index - 1] >>= len;
                }
                else
                {
                        data[index - 1] = data[index - 2] << (8-len) | data[index - 1] >> len;
                }
        }
}

这是我写的一个函数,能实现整体的右移, len:偏移量,data_len是数据长度,单位都是bit,data是需要移动的数据,这个数据的长度,必须比byte_nums大1,因为如果是1个字节偏移的情况,可能需要两个字节来装后面溢出的那一部分。
但是我还是觉得我写的太麻烦,不知道有没有网友可以提供一个更简单的方法
回复 支持 反对

使用道具 举报

8

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2018-12-12
在线时间
16 小时
 楼主| 发表于 2018-12-22 11:26:01 | 显示全部楼层
jackielau 发表于 2018-12-22 11:14
"往左偏移3个bit位  变成 00000001 11100001 11100001"这是右偏移

抱歉抱歉  当时发帖的时候写错了哈哈
回复 支持 反对

使用道具 举报

29

主题

338

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1181
金钱
1181
注册时间
2018-4-13
在线时间
170 小时
发表于 2018-12-23 19:58:37 | 显示全部楼层
Yefeng是叶峰 发表于 2018-12-22 11:24
static void data_offset(uint8_t len, uint8_t data_len, uint8_t* data)
{
        uint8_t byte_nums = (data ...

问一下,你这里的data_len到底是数据长度还是数据数量?
按说应该是数据数量,但是如果是数量的话开始的 data[index] = ......就越界了。
回复 支持 反对

使用道具 举报

29

主题

338

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
1181
金钱
1181
注册时间
2018-4-13
在线时间
170 小时
发表于 2018-12-23 21:07:27 | 显示全部楼层
xiatianyun 发表于 2018-12-23 19:58
问一下,你这里的data_len到底是数据长度还是数据数量?
按说应该是数据数量,但是如果是数量的话开始的 ...

编了一个移动范围为8以内的程序供参考:
void data_offset(unsigned char offset, unsigned char number, unsigned char* pData)
{
        unsigned char* pTemp = pData + number - 1; //pTemp &#214;&#184;&#207;ò×&#238;&#196;&#169;&#210;&#187;&#184;&#246;&#212;&#170;&#203;&#216;×&#214;&#189;&#218;&#163;&#172;&#208;&#161;&#182;&#203;&#196;&#163;&#202;&#189;&#207;&#194;&#202;&#199;×&#238;&#184;&#223;×&#214;&#189;&#218;&#161;&#163;
        for(int i = 0; i < number; i++)
        {
                *pTemp = (*pTemp << offset) | (*(pTemp - 1) >> (8 - offset));
                pTemp--;
        }                       
}
回复 支持 反对

使用道具 举报

8

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2018-12-12
在线时间
16 小时
 楼主| 发表于 2018-12-25 16:43:33 | 显示全部楼层
xiatianyun 发表于 2018-12-23 19:58
问一下,你这里的data_len到底是数据长度还是数据数量?
按说应该是数据数量,但是如果是数量的话开始的 ...

data_len是需要偏移的数据长度  单位是(bit)  比如data_len=16 就两个字节的数据长度
回复 支持 反对

使用道具 举报

8

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
86
金钱
86
注册时间
2018-12-12
在线时间
16 小时
 楼主| 发表于 2018-12-25 17:07:39 | 显示全部楼层
xiatianyun 发表于 2018-12-23 21:07
编了一个移动范围为8以内的程序供参考:
void data_offset(unsigned char offset, unsigned char number ...

十分感谢 我认真研究一下
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-22 23:35

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表