写一个宏,可以将一个整数二进制奇数位和偶数位交换详解

何为一个整数二进制奇数位和偶数位

想要完成解题,我们首先要知道一个整数二进制奇数位和偶数位,具体代表着哪一位

对于一个32位的整型,它的下标是从 0 ~ 31 的,总共32位。

其中下表为0的位是最右边的位(即最低有效位,LSB)

而下标为31的位是最左边的位(即最高有效位,MSB)

当我们说 “偶数位” 的时候,我们指的是下标为偶数( 0 , 2 , 4 …… 30 )的位

当我们说 “奇数位” 的时候,我们指的是下标为奇数( 1 , 3 , 5 …… 31 )的位

步骤1:定义掩码

我们要把一个整数二进制奇数位和偶数位交换,首先想到的就是找掩码来进行操作

何为掩码?掩码通常是一个二进制数,用于选择和屏蔽特定的位

在交换一个整数二进制奇数位和偶数位问题中,掩码用来选则出整数中的奇数位和偶数位。具体我们要用到两个掩码:

1.1偶数位掩码:

一个掩码,其中偶数索引位(从右边数起,第一位开始)是1,其余为是0。对于一个32位整数,它通常是:0x55555555


0101 0101 0101 0101 0101 0101 0101 0101 0101 0101  //(二进制)

5    5    5    5    5    5    5    5    5    5     //(十六进制)

偶数位掩码的作用就是将整数所有的偶数位保留下来( 0 , 2 , 4 …… 30 ),

而奇数位全部清零( 1 , 3 , 5 …… 31 ),具体我们可以使用:

按位与 (&)来操作

通过这样的操作,我们就将 所有的偶数位保留下来,而奇数位全部清零了

1.2奇数位掩码:

一个掩码,其中奇数位索引的位为1,其余是0对于一个32位整数,它通常是:0xAAAAAAAA

奇数位掩码的作用就是将整数所有的奇数位保留下来,而奇数位全部清零。

步骤2:位操作

接下来,我们使用位操作来交换奇数位和偶数位

  • 将整数与偶数位掩码0x55555555进行按位与操作(&),得到只包含偶数位信息的数。
  • 将这个只包含偶数位信息的数左移一位(<< 1),使原来的偶数位占据奇数位的位置。
  • 同时,将整数与奇数位掩码0xAAAAAAAA进行按位与操作(&),得到只包含奇数位信息的数。
  • 将这个只包含奇数位信息的数右移一位(>> 1),使原来奇数位占据偶数位的位置
     

步骤3:合并结果

最后,我们将左移后的偶数位和右移后的奇数位通过:

按位或操作( | ),或者加号( + )合并起来,得到最终交换了奇数位和偶数位的整数。

宏的最终实现

#define SWAPa(x) ( \
    (((x) & 0x55555555) << 1) | \
    (((x) & 0xAAAAAAAA) >> 1) \
)
#define SWAb(x) ( \
    (((x) & 0x55555555) << 1) + \
    (((x) & 0xAAAAAAAA) >> 1) \
)
int main() {

    printf("%d\n", SWAPa(5));
    printf("%d\n", SWAPa(5));

    printf("%d\n", SWAPa(10));
    printf("%d\n", SWAPa(10));

    return 0;
}

输出结果:10 10 5 5

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值