蝶式交换,字节高低位交换

157 篇文章 ¥9.90 ¥99.00
本文介绍了如何对一个字节数据进行高低位交换,详细讲解了使用蝶式交换法的原理和步骤,并提供了相应的C语言实现代码。通过对字节的移位操作,实现了位序的逆序转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题
对一个字节数据,逐个交换其高低位,例如11010001,经过0-7,1-6,2-5,3-4对应位的交换,变成10001011 。

解决思路
对于该问题,我们最先想到的是对原字节通过移位操作来逐位处理,使用另一个变量来存储交换后的结果。这种解决方案处理起来思路清晰,编写代码应该不难。

下面是该思路对应的代码:


unsigned char shift_fun1(unsigned char data)
{
    unsigned char i;
    unsigned char tmp=0x00;
 
    for(i=0;i<8;i++)
    {
        tmp=((data>>i)&0x01)|tmp;
        if(i<7)
            tmp=tmp<<1;
    }
 
    printf("  after shift fun1 data=%x \n",tmp);
 
    return tmp;
    
}

上述代码实现起来不难,而且效率还是比较高的。但是还有比这更简洁的解决方法,在嵌入式开发中遇到交换字节位的问题时通常使用蝶式交换法和查表法来实现。查表法顾名思义即将一些值存到内存中,需要计算时查表即可,但是也会占用额外的存储空间。这里主要再介绍一下蝶式交换法。
所谓的蝶式交换是这样的:


    data=(data<<4)|(data>>4);
    data=((data<<2)&0xcc)|((data>>2)&0x33);
    data=((data<<1)&0xaa)|((data>>1)&0x55);

我们可以做一下执行演算:
假设原始位序列为  0 1 0 1  1 0 0 1  

data=(data<<4)|(data>>4);之后序列为  1 0 0 1  0 1 0 1

data=((data<<2)&0xcc)|((data>>2)&0x33);  之后序列为  0 1 1 0  0 1 0 1

data=((data<<1)&0xaa)|((data>>1)&0x55);  之后序列为 1 0 0 1  1 0 1 0

更抽象的来说 原始位为 1 2 3 4  5 6 7 8

data=(data<<4)|(data>>4); 之后位序为  5 6 7 8  1 2 3 4

data=((data<<2)&0xcc)|((data>>2)&0x33);   之后位序为  7 8 5 6  3 4 1 2

data=((data<<1)&0xaa)|((data>>1)&0x55);   之后位序为  8 7 6 5  4 3 2 1  

由此完成了整个位的逆序转换,下面是具体的实现代码:


unsigned char shift_fun2(unsigned char data)
{
    data=(data<<4)|(data>>4);
    data=((data<<2)&0xcc)|((data>>2)&0x33);
    data=((data<<1)&0xaa)|((data>>1)&0x55);
    printf("  after shift fun2 data=%x \n",data);
 
    return data;
}

总结
交换字节的高低位并不是一个很常见的问题,遇到该问题时,需要经过仔细的分析,加上对C语言位操作的熟练掌握,就能够很好的解决这一类的问题。
--------------------- 
作者:syzcch 
来源:优快云 
原文:https://blog.youkuaiyun.com/syzcch/article/details/8149706 
版权声明:本文为博主原创文章,转载请附上博文链接!

### 单片机中实现数据高低位交换的方法 #### 使用按位操作实现高低位交换 一种常见的方法是通过按位移位和逻辑运算来完成高低位交换。对于一个字节的数据,可以采用如下方式: ```c unsigned char swap_nibbles(unsigned char data) { return ((data << 4) & 0xF0) | ((data >> 4) & 0x0F); } ``` 这段代码先将输入`data`左移四位并保留高四位不变;再将其右移四位得到低四位的结果,最后两者相或即实现了整个字节内高低 nibble 的位置调换[^1]。 #### 蝶式交换法 另一种更复杂但也更为灵活的方式称为“蝶式交换”,适用于多位数之间的特定模式变换。例如给定序列 `0b0110_0101` 经过一次蝶形变化后变为指定的新排列形式: ```python data = (data << 2) & 0xcc | (data >> 2) & 0x33; // 这里假设初始值为二进制表示下的 '0110_0101' // 执行上述语句后的结果会变成新的比特串'0011_1010' ``` 此过程利用掩码(`0xCC`, `0x33`)控制哪些位参与移动以及它们的目标位置。 #### 利用位寻址特性 针对某些支持位级访问指令集架构(ISA)如MCS-51系列单片机,则可以直接操纵各个单独的位来进行更加精细的操作。下面给出了一种基于此类硬件特性的解决方案: ```c unsigned char Switch_bit(unsigned char InChar){ unsigned char bdata B; // 定义用于存储反转后的字符变量B sbit B7=B^7;sbit B6=B^6;sbit B5=B^5;sbit B4=B^4; sbit B3=B^3;sbit B2=B^2;sbit B1=B^1;sbit B0=B^0; unsigned char bdata C; // 中间过渡变量C保存原始输入InChar sbit C7=C^7;sbit C6=C^6;sbit C5=C^5;sbit C4=C^4; sbit C3=C^3;sbit C2=C^2;sbit C1=C^1;sbit C0=C^0; C = InChar; B0=C7;B1=C6;B2=C5;B3=C4; B4=C3;B5=C2;B6=C1;B7=C0; return B; } ``` 该函数接收一字节作为参数并通过逐一对每位取反达到完全翻转的效果[^3]。 当涉及到多于一个字节的情况时,还需要考虑系统的字节序问题——即大端还是小端模式。这决定了高位字节是在较低地址处还是较高地址处存放,在跨平台移植程序时尤其需要注意这一点[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值