交换一个整数二进制表示中的奇数位和偶数位

题目

原文:

写程序交换一个整数二进制表示中的奇数位和偶数位,用尽可能少的代码实现。 (比如,第0位和第1位交换,第2位和第3位交换…)

解答

这道题目比较简单。分别将这个整数的奇数位和偶数位提取出来,然后移位取或即可。

代码如下:

int swap_bits(int x){
    return ((x & 0x55555555) << 1) | ((x >> 1) & 0x55555555);
}

当然也可以采用更自然的方式来写这段代码:

int swap_bits1(int x){
    return ((x & 0x55555555) << 1) | ((x & 0xAAAAAAAA) >> 1);
}

上面的代码思路和作用都是一样的,不过按照《Hacker’s delight》这本书里的说法, 第一种方法避免了在一个寄存器中生成两个大常量。如果计算机没有与非指令, 将导致第二种方法多使用1个指令。总结之,就是第一种方法更好。

时间: 2024-12-25 03:35:34

交换一个整数二进制表示中的奇数位和偶数位的相关文章

交换整数的奇数位和偶数位

今天在一本书上看到一题:编写程序交换某个整数的奇数位和偶数位,使用指令越少越好(即位0与位1交换,位2与位3交换).看过题目解析之后才发觉,这题要交换的是整数二进制的奇数和偶数位. 按照一般的解题肯定会对每一位分别处理,即,将整数换成二进制,然后遍历一遍,交换奇数位和偶数位.这样效率不高,指令也不少.然后看大题目解析,感觉用位操作很棒,以下为解题思路: (1)先操作奇数位,把101010(即0xAA)作为掩码,提取奇数位,并右移1位到偶数位置 (2)操作偶数位,把010101(即0x5555)作

9.5位操作(六)——交换某个整数的奇数位和偶数位,使用指令越少越好

/** * 功能:交换某个整数的奇数位和偶数位,使用指令越少越好(即,位0与位1交换,位2与位3交换,以此列推). */ /** * 思路:先操作奇数位,再操作偶数位.将数字n的奇数位右移1位,偶数位左移1位. * @param x * @return */ public static int swapOddEvenBits(int x){ //奇数位右移,0xaaaa aaaa=10101010 10101010 10101010 10101010 10101010 10101010 1010

c语言:输入两个整数m和n,计算需要改变m的二进制表示中的多少位才能得到n

输入两个整数m和n,计算需要改变m的二进制表示中的多少位才能得到n? 解:第一步求这两个数的异或运算,将异或运算结果存起来:第二步统计这个运算结果当中1的位数 程序: #include<stdio.h> int count(int m,int n) { int t,count=0; t = m^n; while (t) { count++; t=t&(t-1); } return count; } int main() { int num1,num2,ret=0; printf(&qu

使用一个整数字段保存多个状态位数据

如今,各种大小网站经常搞各种推广优惠活动,吸引新用户,回馈老用户.如何方便快捷地记录和查询用户参与某项活动的数据是开发人员必须面对的问题. 方法一:记录用户参与活动数据到记录详情表中,查询该表一定可以获得用户的参与状态. 方法一缺点:需要单独执行一次查询操作,如果参与记录表数据量大,查询效率又是个问题. 方法二:在用户基本信息表中添加状态位字段,用户参与活动成功后,更新状态位字段,查询参与状态时直接读取基本信息中的相应字段. 方法二缺点:活动数量增加时,状态位字段必须相应增加,表中字段过多不是什

笔试算法题(14):整数二进制表示中的1 &amp; 判定栈的push和pop序列是否对应

出题:输入一个整数,要求计算此整数的二进制表示中1的个数 分析: 如果整数表示为k,当其是负数的时候,使用1<<i分别检测k的每一位:当其位整数的时候,则k/2表示将其二进制表示右移一位,k%2 ==0表示其是否是偶数,如果不是则说明当前二进制表示的最右边一位为1,当k==0成立的时候移位结束: 另外还可以使用'消1'的方法,如果二进制表示A为'****1000',则A-1为'****0111',也就是我们仅关注二进制表示最右边的第一个 1,这样的话A&(A-1)的结果就可以将最右边的

22.整数二进制表示中1的个数

http://zhedahht.blog.163.com/blog/static/2541117420073118945734/ 另外一种思路是如果一个整数不为0,那么这个整数至少有一位是1.如果我们把这个整数减去1,那么原来处在整数最右边的1就会变成0,原来在1后面的所有的0都会变成1.其余的所有位将不受到影响.举个例子:一个二进制数1100,从右边数起的第三位是处于最右边的一个1.减去1后,第三位变成0,它后面的两位0变成1,而前面的1保持不变,因此得到结果是1011. 我们发现减1的结果是

返回一个整数循环数组中最大子数组的和

要求:      输入一个整形数组,数组里有整数也有负数.      数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.      如果数组A[0]--A[j-1]首尾相邻,允许A[i-1],--A[n-1],A[0]--A[j-1]之和最大.      同时返回最大子数组的位置. 求所有子数组的和的最大值. 思路:循环两次,进行排除法,判断数组中每个数所构成的最大子数组,然后将数组中每个数对应的最大子数组进行判断,最后得到这个整数数组的最大子数组. #include<iostre

C++ 算法之 输入两个整数m n,求计算需要改变m的二进制表示中的多少位才能得到n

思路:先把m与n进行异或运算,再统计异或结果当中的1的个数: 异或:相同为0,不同为1: 0^0 = 0; 1^1 = 0; 0^1 = 1; 1^0 = 1; 比如10 : 1010 :  13:1101: 10^13  ------>    1 0 1 0 1 1  0 1 结果                   0  1 1 1 异或有几个不同为就会有几个1:统计1的个数就知道需要改变几位了 // changeNumber.cpp : 定义控制台应用程序的入口点. // #include

求一个整数中二进制1的个数

题目:求一个整数二进制表示1的个数 第一版: 思路:如果一个整数与1做与运算,结果为1,那么该整数最右边一位是1,否则是0: int NumberOf1(int n) { int count = 0; while (n) { if (n&1)//如果一个整数与1做与运算的结果是1,表示该整数最右边是1,否则是0: { count++; } n = n>>1; } return count; } 缺点:因为代码当中有右移,当是负数的时候,要考虑符号位:如果一个正数,右移之后在最左边补n个