C++: 位操作
2016-05-07 11:29
330 查看
使用位操作加快运行
位运算的知识
有效的计算2乘以8的方法
快速求取一个整数的7倍
实现位操作求两个数的平均值
引申利用位运算计算数的绝对值
不用除法操作符实现两个正整数的除法
方法一
方法二递归求解
方法三移位操作
引申1用逻辑运算实现加法运算
引申2如何只用逻辑运算实现乘法运算
(2)获取整数n的二进制中最后一个 1:n&(-n) 或者 n&~(n-1)。例如,n = 010100, 则 -n = 101100,n&(-n) = 000100
(3)去掉正数n的二进制总的最后一个1:n&(n-1),如 n=010100, n-1 = 010011, n&(n-1)=010000
常规的乘法运算也可以实现,但CPU直接支持位运算,效率最高,所以操作最有效的方法是2<<3
注意:由于 -的优先级高于 << 所以不能去掉括号,否则结果不正确
但是采用上述方法,会存在一个问题,当两个数比较大时,如两者的和大于了机器位数能够表示的最大值,可能会存在数据溢出的情况,而采用位运算的方法则可以避免这一问题,
对于表达式
整个表达式实际上可以分为两部分,第一部分是都为1的部分,因为相同,所以直接相加即可;而第二部分是x为1,y为0的部分以及x为0,y为1的部分,两部分加起来再除以2,然后跟前面的相加就可以表示两者的平均数了。
对一个正数,右移31位后变成0x00000000
而0xffffffff^x + x = -1 ;因为1011^1111 = 0100,任何数与1111异或,实质是把x的0和1进行颠倒计算。
如果用变量y表示x右移31位,(x^y)-y 则表示的是x的绝对值
位运算的知识
有效的计算2乘以8的方法
快速求取一个整数的7倍
实现位操作求两个数的平均值
引申利用位运算计算数的绝对值
不用除法操作符实现两个正整数的除法
方法一
方法二递归求解
方法三移位操作
引申1用逻辑运算实现加法运算
引申2如何只用逻辑运算实现乘法运算
位运算的知识
(1)常用的等式: -n = ~(n-1) = ~n+1(2)获取整数n的二进制中最后一个 1:n&(-n) 或者 n&~(n-1)。例如,n = 010100, 则 -n = 101100,n&(-n) = 000100
(3)去掉正数n的二进制总的最后一个1:n&(n-1),如 n=010100, n-1 = 010011, n&(n-1)=010000
有效的计算2乘以8的方法
虽然直接进行乘法操作符运算也可以进行2*8,但是这种方法并非最优,通过移位的方法会比较高效。将一个数左移n位,相当于乘以了2的n次方。常规的乘法运算也可以实现,但CPU直接支持位运算,效率最高,所以操作最有效的方法是2<<3
快速求取一个整数的7倍
( X < < 3 ) - X
注意:由于 -的优先级高于 << 所以不能去掉括号,否则结果不正确
实现位操作求两个数的平均值
求解平均数的方法就是将两者相加,然后除以2,以变量x与y为例,两者的平均数为(x+y)/2.但是采用上述方法,会存在一个问题,当两个数比较大时,如两者的和大于了机器位数能够表示的最大值,可能会存在数据溢出的情况,而采用位运算的方法则可以避免这一问题,
(x&y)+((x^y)>>1)就是求解变量x与y的平均数,且位运算相比除法运算,效率更高。
对于表达式
(x&y)+((x^y)>>1)中,
x&y表示的是取出x与y二进制位数中都为1的所有位,
x^y表示的是x与y中有一个为1的所有位,右移1位相当于执行除以2运算。
整个表达式实际上可以分为两部分,第一部分是都为1的部分,因为相同,所以直接相加即可;而第二部分是x为1,y为0的部分以及x为0,y为1的部分,两部分加起来再除以2,然后跟前面的相加就可以表示两者的平均数了。
引申:利用位运算计算数的绝对值
对一个负数,右移31位后变成 0xffffffff对一个正数,右移31位后变成0x00000000
而0xffffffff^x + x = -1 ;因为1011^1111 = 0100,任何数与1111异或,实质是把x的0和1进行颠倒计算。
如果用变量y表示x右移31位,(x^y)-y 则表示的是x的绝对值
不用除法操作符实现两个正整数的除法
方法一:
根据除法运算的原理进行减法操作,对除数循环减去被除数,减一次结果加一,直到刚好减为0或余数小于被除数为止int div( int a, int b ) { int result = 0; if( b==0 ) { cout << "除数不能为0" << endl; return result; } while( a>b ) { result++; a = a-b; } return result; }
方法二:递归求解
方法三:移位操作
引申1:用逻辑运算实现加法运算
实现两个正整数相加,一般直接使用加号运算符即可。根据题目中的要求,与上例中的方法二类似,可以通过移位操作符来进行正整数的加法运算。例如,5与7求和,转换为二进制求和为101与111求和,其二进制结果为1100.对于二进制的加法而言,1+1=0, 1+0=1, 0+0=0,通过对比位运算中的异或方法,不难发现,此方法与位运算中的异或类似。那么第一个数值就是:tempNum1 = num1^num2;0+0的进位是0,0+1的进位是0,只有1+1的进位是有效的,该思路与位运算的&运算相似,所以可以先 num1&num2,由于进位是进到高一位的,与<<运算很相似,同时num1和num2相互&之后,如果结果为0,那么久不存在进位,运算完成,所以可以用递归的思想实现。引申2:如何只用逻辑运算实现乘法运算
此乘法,不大懂。。。相关文章推荐