欢迎转载,转载请注明出处:http://www.zhutibo.com/action/subject874.htm
位操作主要应用:
位操作主要用在驱动、嵌入式等底层开发中;以前做Android开发时,发现人家做驱动的使用位操作真是相当频繁,有些情况下,每一位代码什么都写得明明白白;尤其是那些寄存器操作时用到的更多。除此之外,通信领域也是用得非常多的,这点可想而知;尤其是在无线通信,每一位都是非常精贵的,还记得我几年前去面试一个深圳通信公司,那给的就是一道用C操作一个IP的题目,就是要求用位操作实现,细节就不说了。
操作对象:
在讲具体位操作之前,我们首先需要知道数字在计算机里是怎么存储的:计算机里的数字是以补码的方式存储的。
补码定义:
- 正数的补码就与原码相同
- 负数的补码就是除符号位之外取反,然后整个数再加1
- 0的补码为0000 0000(考虑8位存储)
- -128的补码为1000 0000(由公式2^8-2^7计算得出,不能由之前定义得出)
补码存储带来的好处:
- 减法按加法处理
- 符号位同其它位一同处理
- 两个补码相加的,如果最高位有进位,那进位自动舍弃。
在不考虑溢出等情况:负数的补码最左边的1,相当于正数最左边的0,可以随便补。知道这点对之后的移位操作很有用。
位操作符
& 与
| 或
^ 异或:相同为0相异为1
~ 非
>> 算术右移(移位后左空位补法:正数补0,负数补1)
<< 算术左移(移位后右空位补0)
>>> 逻辑右移(左空位一率补0,不考虑正负)
举几个典型例子(考虑Java中的整型,如果是C的话,与具体环境有关,例子不能通用):
// x右数第三位值是否为1
0x04&x==0x04
// 把右数第三位置1
x = 0x04 | x;
// -128(1000 000 00000000 00000000 00000000)向左移一位
println( Integer.MIN_VALUE<<1 ); //值应当为0
// 把-2(11111111 11111111 11111111 1111 1110)向右算述移位
println( -2>>1 ); //值应当为-1
// 把-2向右逻辑移位
println( -2>>>1 ); //值应当为2147483647