C++: 位操作
来源:互联网 发布:淘宝买家信誉度是什么 编辑:程序博客网 时间:2024/06/09 21:55
使用位操作加快运行
- 位运算的知识
- 有效的计算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倍
- 1
- 1
注意:由于 -的优先级高于 << 所以不能去掉括号,否则结果不正确
实现位操作求两个数的平均值
求解平均数的方法就是将两者相加,然后除以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或余数小于被除数为止
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
方法二:递归求解
方法三:移位操作
引申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:如何只用逻辑运算实现乘法运算
此乘法,不大懂。。。
- C的位操作
- C语言 位操作
- C 位操作
- c++(位操作符)
- C语言位操作
- C-位操作
- C语言位操作
- C/C++位操作
- C 位操作 详解
- C语言位操作
- C语言位操作
- C语言位操作
- C 位操作
- C 位操作
- c语言位操作
- C语言位操作
- c语言位操作
- C语言-位操作
- day16(LinkedList)
- 实现选择排序和堆排序——题集(十六)
- jQuery解析xml文件,使用get方法实现省市县三级联动下拉框
- 欢迎使用CSDN-markdown编辑器
- 简单原生js实现开关门效果
- C++: 位操作
- 第一个maven示例-helloworld
- 感悟到,想写博客
- 职业生涯系列
- Qt pro文件配置多个子工程/子模块
- CloudStack管理员文档
- 由于安全加固引起的数据库不能访问
- 并发数据结构:谈谈volatile变量
- C++:fstream类中seekg()/seekp()与tellg()/tellp()的用法详解