位运算

概念

 1. 原码

  当前数字的二进制表现形式,其中第一位为符号位;

  +1 原码为 0000 0001

  -1 原码为 1000 0001

2.反码

  正数的反码就是原码,负数的反码是符号位不变,其余位取反;

  +1 反码为 0000 0001

  -1 反码为 1111 1110

3. 补码 

  正数的补码就是原码,负数的补码是反码+1;

  +1 补码为 0000 0001

  -1 补码为 1111 1111

注意

  对于正数,三种编码方式的结果都是相同的;而负数的原码、反码、补码各不相同;  

  计算机为什么使用补码?

  使用原码时,人脑可以知道第一位是符号位,对于计算机来说,辨别符号位会使电路的设计变得十分复杂;而使用补码,不仅可以将符号位参与运算,而且计算机可以只有加法而没有减法,简化计算机运算的设计。关于计算机使用补码更详细介绍可参考http://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html#!comments

位运算  

运算符 名称 描述 样例
& 按位与 如果相对应位都是1,则结果为1,否则为0

   60=0011 1100

   13=0000 1101

 60&13=0000 1100=12  

| 按位或 如果相对应位都是0,则结果为0,否则为1   60|13=0011 1101=61  
^ 按位异或 如果相对应位值相同,则结果为0,否则为1  60^13=0011 0001=49 
~ 按位取反 翻转操作数的每一位,即0变成1,1变成0。(一元运算符)      ~60=1100 0011=-60  
<< 左移 左操作数按位左移右操作数指定的位数,右边补0,符号位也参与运算  60<<2=1100 0000=240
>> 右移 左操作数按位右移右操作数指定的位数,左边补符号位,符号位也参与运算   60>>2=0000 1100=15
>>> 逻辑右移 左操作数按位右移右操作数指定的位数,左边补0,符号位也参与运算  60>>2=0000 1100=15

注意

  左移:将二进制每一位(包括符号位)左移,左边超出的位截掉,右边补0;

     a为正数时,a<<n=a*2,a为负数不符合这个规则;

    -2147483647 << 1 = 10000000 00000000 00000000 00000001 << 1

              = 00000000 00000000 00000000 00000010 = 2

  右移:将二进制每一位(包括符号位)右移,右边超出的位截掉,左边补符号位;负数还是负数,正数还是正数;

     a!=-1时,a>>n=a/2;-1>>1=-1;

    -2147483647 >> 1 = 10000000 00000000 00000000 00000001 >> 1

              = 11000000 00000000 00000000 00000000 = -1073741824

  逻辑右移:将二进制每一位(包括符号位)右移,右边超出的位截掉,左边0;结果都是一个正数;

    -2147483647 >>> 1 = 10000000 00000000 00000000 00000001 >> 1

                = 01000000 00000000 00000000 00000000 = 1073741824

小技巧

1. 获取整数n二进制的最后一位是0或1:n&1

  33= 00000000000000000000000000100001

    1= 00000000000000000000000000000001  33&1 = 1

  32= 00000000000000000000000000100000

    1= 00000000000000000000000000000001  32&1 = 0

2. 判断奇偶: n&1 或者n|0

3. 清零最低位的1 :n = n&(n-1)

4. 得到最低位的1:n&(-n)

应用

1. 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。(备注11)

原文地址:https://www.cnblogs.com/zhacai/p/9592798.html