二进制:位操作运算符

1, 二进制

  数据在内存中是用二进制存储的,二进制是指由0,1两个元素组成。

  其常见的编码方式有三种:原码,反码,补码

2 ,位

  内存中最小存储单元是位,也称为bit。常常用8个bit存储一个字符,即1Byte=8bit。

3 ,位操作

  是指cpu对内存中的二进制数进行操作。

  包括&(与)、|(或)、^(异或)、~(非)、<<(按位左移)、>>(按位右移)六个操作符。

  3.1 双目运算符

    是指参与运算的有两个数。下面括号内分别表示两个数。

    &:if (1,1)?1:0

    |:if (1,0) or (0,1) ?1:0

    ^:if (0,0) or (1,1)?0:1

    <<:向左按位进N位,低位补0。

    >>:向右按位进N位,低位舍弃。

  3.2 单目运算符

   是指参与运算的数的本身,即一个数。

   ~:if 1?0:1

4, 原码

  指真实的二进制编码。

  当数是有符号的整数,最高位用来表示正负,1表示负,0表示正,其余位表示数值的大小。 

                  8位原码
  二进制     有符号     无符号
  00000000   +0       0
  00000001   1        1
  ...       ...        ...
  01111111   127       127
  10000000   −0       128
  10000001   −1       129
  ...       ...         ...
  11111111   −127      255

  即十进制5=二进制0000 0101,-5=1000 0101。

  一个字符所占的空间是00000000~11111111.

  两个正数相加,即逢2进1.

  两个负数的加法就很简单了,把结果保留符号位,然后按照正数加法运算即可。

  由于cpu中没有减法器电路,原码就没办法执行减法运算,只能由一个正数加一个负数,显示是计算出来的结果是错误的。

  比如:5+(-)5=1000 1010=-10(错误)

  注意到此时有符号数:~(+0)=-127,~1=-126...~127=-0

  所以引出反码。

5, 反码

  反码是指对有符号数逐位取反,保留符号位;无符号数反码与原码相同。

  即:反码=~原码|1000 0000

                    8位反码
  二进制值   反码表示   无符号数表示
  00000000   +0          0
  00000001   1             1
  ...       ...           ...
  01111101   125         125
  01111110   126           126
  01111111   127               127
  10000000      −127      128
  10000001   −126       129
  10000010   −125         130
  ...       ...        ...
  11111110   −1      254
  11111111   −0        255

  如上,注意到实际上是把原码表中的负数部分上下对调。即-127调到-0的位置,如此类推。

  如何调换位置呢?想一想链表,原理类似,只要把除符号位以外的元素进1位即可。

  那么反码+反码的结果就是表中所示,如果要映射到原码表,进一位即可。

  所以减法的计算公式:结果+0000 0001(十进制1)

  下面来计算减法:

  那么(-1)+2=1111 1110

         + 0000 0010

       + 0000 0001

         = 0000 0001    

6,补码

  补码是指对有符号数逐位取反,保留符号位,然后再加1;无符号数反码与原码相同。

  回头再看看反码的减法,需要进行三步操作,即建立反码表、加法、映射到原码表(结果加1)。而且表中还存在两个0,浪费了宝贵的内存空间。

  为了解决进位加1,和减少内存空间的浪费,所以提出了补码。

  补码是反码表加1,即补码=~原码|1000 0000+ 0000 0001

         8位补码
  二进制值     补码表示     无符号数表示
  00000000     0         0
  00000001     1         1
  ...         ...         ...
  01111110     126         126
  01111111     127         1275
  10000000     −128       128
  10000001     −127       129
  10000010     −126       130
  ... ... ...
  11111110     −2        254
  11111111     −1        255

   下面来计算减法:

  那么(-1)+2=1111 1111

         + 0000 0010

         = 0000 0001    

  内存中的数是用补码表存储的。

7,常用的位操作技巧

  7.1 判断一个正整数是奇数还是偶数

  很显然在二进制中只要判断最后一位是否是0还是1,0即偶数,1为奇数。

  即:a&1

  实际上我们可以看到&起到一个只对自己关心的位置操作的作用。有的地方叫着掩码也正是这个意思。

  如果只是想操作某一个数的第2,3位,可以用a&0000 0110

  7.2 交换数不用临时变量

  x^=y;

  y^=x;

  x^=y;

  参考资料来源:

  1.http://zh.wikipedia.org/wiki/%E6%9C%89%E7%AC%A6%E8%99%9F%E6%95%B8%E8%99%95%E7%90%86

  2.http://blog.csdn.net/liufei_learning/article/details/6273786

  3.http://aggregate.ee.engr.uky.edu/MAGIC/

  4.http://blog.csdn.net/superdullwolf/article/details/4649080

  5.http://blog.csdn.net/morewindows/article/details/7354571

原文地址:https://www.cnblogs.com/273809717/p/2815099.html