• 二进制:位操作运算符


    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

  • 相关阅读:
    Python学习笔记(尚硅谷)——变量
    四级高频词-工作类
    转载--JS根据浏览器的useAgent来判断浏览器的类型
    MySQL上传文件容量过大com.mysql.jdbc.PacketTooBigException
    关于<input type="file" >浏览器兼容问题
    IDictionary与TryGetValue
    生成自增ID列
    利用C#将PCM格式的Wav进行对文件裁剪截取、淡入淡出、保存为音频文件相关详细代码解释
    DevExpress控件学习总结
    C# 音频操作系统项目总结
  • 原文地址:https://www.cnblogs.com/273809717/p/2815099.html
Copyright © 2020-2023  润新知