• 位运算(转)


    在博客园潜水好久了,今天兴致高昂的想写一篇博客,写的内容就是最近刚刚弄懂的关于位运算的题目。可能对那些老鸟老说这些是在基础不过的东西了,但是我相信还是有很多的博客需要了解并掌握这个基础的。

    做题目前首先需要掌握的知识:

    ~           取反运算符,如果运算位为1取反后则变为0,如果运算为为0取反后则为1

    &           与运算符,当运算的两个数同时为1时,则与运算的结果才为1,否则为0

    |             或运算符,当运算的两个数只要有一个1时,则或运算的结果为1,否则为0.

    ^    异或运算符,当两个运算位不同时为1,相同时是0

    >>          右移运算符

    <<          左移运算符

    在内存中的运算都是以补码的形式存在的。

    正数的原码、反码、补码相同。

    负数的原码:最高为符号为0代表正、1代表负。后面的数为整数转换后的二进制数。

    负数的反码:除符号为以外的位进行取反,1变为0,0变为1

    负数的补码:负数的反码+1

    这里举个简单的负数的例子,这里以整数占4个字节为例:

    整数-5

    (-5)10 的原码为:(10000000 00000000 00000000 00000101)2

    (-5)10 的反码为:(11111111 11111111 11111111 11111010)2

    (-5)10 的补码为:(11111111 11111111 11111111 11111011)2

    算术右移:低位溢出,符号位不变,并用符号位补溢出的高位。

    算术左右:符号位不变,低位补0

      基础知识就这么点了。不过这里没有必要死记,在一边做题目的时候,一边在看定义,这样对于理解会很有帮助的。

    题目1

    ~2        

      因为:2为正数,所以2的原码等于2的反码等于2的补码

      因为计算中的运算都是以补码的形式存在的。所以我们需要2的补码为(00000000 00000000 00000000 00000010)2

      对2的补码进行取反运算得到:         (11111111 11111111 11111111 11111101)2

      此时得到的结论为(~2)的补码为       (11111111 11111111 11111111 11111101)2

      因为最高位为1,所以是负数看,负数的补码等于负数的反码+1

      所以又可以得到了(~2)的反码为        (11111111 11111111 11111111 11111100)2

      根据反码又可以得到(~2)的原码为       (10000000 00000000 00000000 00000011)2

      最后我们把二进制数转化为十进制数-3.

      所以~2=-3

                 

    题目2

    2&3 2|3

      因为2、3都为正数,所以2、3的原码等于反码等于补码。

          即(2)10的原码、反码、补码为         (00000000 00000000 00000000 00000010)2

            (3)10的原码、反码、补码为          (00000000 00000000 00000000 00000011)2

          紧接着我们开始与运算

                                            00000000 00000000 00000000 00000010

                                      &   00000000 00000000 00000000 00000011


                                00000000 00000000 00000000 00000010

     

      在接着我们开始或运算

                                            00000000 00000000 00000000 00000010

                                      |       00000000 00000000 00000000 00000011


                               00000000 00000000 00000000 00000011

      这与、或运算的结果为补码,我们还需要进行转化成原码。

          因为最高为0(符号位),所以表示整数。

      即原码等于反码等于补码。

      所以2&3的原码用二进制表示为         00000000 00000000 00000000 00000010

          转化成十进制为2

      2|3的原码用二进制表示为          00000000 00000000 00000000 00000011

          转化成十进制为3

    题目3

    13&7

      同样我们可以从题目中知道13、7都是正数,所以正数的原码等于反码等于补码。

          即(13)10的原码等于反码等于补码为    (00000000 00000000 00000000 00001101)2

    (7)10的原码等于反码等于补码为         (00000000 00000000 00000000 00000111)

      最后我们在脑子里模拟在内存中的运算:

                            00000000 00000000 00000000 00001101

                                   &      00000000 00000000 00000000 00000111


                               00000000 00000000 00000000 00000101

      从结果中我们可以看出补码的最高位符号位为0表示正数。

      所以(13&7)10的原码等于       (00000000 00000000 00000000 000000101)2

      转化成十进制数为5

    题目4

    5|4         

      同样我们可以从题目中知道5、4都是正数,所以正数的原码等于反码等于补码。

          即(5)10的原码等于反码等于补码为    (00000000 00000000 00000000 00000101)2

      (4)10的原码等于反码等于补码为     (00000000 00000000 00000000 00000100)

      最后我们在脑子里模拟在内存中的运算:

                            00000000 00000000 00000000 00000101

                                     |   00000000 00000000 00000000 00000100


                             00000000 00000000 00000000 00000101

      从结果中我们可以看出补码的最高位符号位为0表示正数。

      所以(5|4)10的原码等于       (00000000 00000000 00000000 000000101)2

      转化成十进制数为5

    整数相对而言还是相对简单得,接着我们在来看几个负数的题目。

    题目5

    (~-5)

      首先我们可以知道-5是负数

          所以我们要先转化成原码

          (-5)10的原码为         (10000000 00000000 00000000 00000101)2

           在转化成为反码

      (-5)10的反码为          (11111111 11111111 11111111 11111010)2

      在转化成为补码

      (-5)10的补码为          (11111111 11111111 11111111 11111011)2

           得到了补码我们可以开始取反运算了:

          (~-5)10的补码为         (00000000 00000000 00000000 00000100)2

           这里可以看到最高为符号位为0,所以表示的是整数。

           正数的原码等于反码等于补码。

           所以(~-5)10的原码为       (00000000 00000000 00000000 00000100)2

           最后(~-5)=4

      

      

      紧接着我们来看左移运算符和右移运算符。

     题目6

    -1>>2

      因为是-1是负数,所有我们先通过一系列的转化得到他的补码。

         (-1)10 的原码为:    (10000000 00000000 00000000 00000001)2

      (-1)10 的反码为:       (11111111 11111111 11111111 11111110)2

      (-1)10 的补码为:     (11111111 11111111 11111111 11111111)2

             紧接着我们开始右移运算,溢出位用符号位来补。右移2位得到

      (-1>>2)10 的补码为:  (11111111 11111111 11111111 11111111)2

           因为符号位为1,所以是负数,我们接着算出反码,原码。

      (-1>>2)10 的反码为:  (11111111 11111111 11111111 11111110)2

      (-1>>2)10 的原码为:  (10000000 00000000 00000000 00000001)2

       所有-1>>2=-1

     

    -1<<2

          我直接用上面的到的

      (-1)10 的补码为:     (11111111 11111111 11111111 11111111)2

           紧接着我们在对他进行左移,低位用0补。左移两位得到的结果是

      (-1<<2)10 的补码为:   (11111111 11111111 11111111 11111100)2

      因为符号位为1,所以是负数,我们接着算出反码,原码。

      (-1<<2)10 的反码为:   (11111111 11111111 11111111 11111011)2

      (-1>>2)10 的原码为:   (10000000 00000000 00000000 00000100)2

      所有-1<<2=-4

     

    题目7

    1>>2

      因为1是正数,所有原码等于反码等于补码,即

      (1)10 的原码等于反码等于补码为 (00000000 00000000 00000000 00000001)2

      紧接着我们开始右移运算,

      (1>>2)10 的补码为       (00000000 00000000 00000000 00000000)2

      因为符号位为0,所有原码等于反码等于

      补码为              (00000000 00000000 00000000 00000000)2

      所有1>>2=0

     

    1<<2

      因为1是正数,所有原码等于反码等于补码,即

      (1)10 的原码等于反码等于补码为 (00000000 00000000 00000000 00000001)2

      紧接着我们开始右移运算,

      (1>>2)10 的补码为        (00000000 00000000 00000000 00000100)2

      因为符号位为0,所有原码等于反码等于

      补码为              (00000000 00000000 00000000 00000100)2

      所有1<<2=4

     

    题目8

    -3^3

           首先-3的为负数,所以

      (-3)10 的原码为       (10000000 00000000 00000000 00000011)2

      (-3)10 的反码为       (11111111 11111111 11111111 11111100)2

      (-3)10 的原码为       (11111111 11111111 11111111 11111101)2

      在因为3为正数则

      (3)10 的原码等于反码等于补码为 (00000000 00000000 00000000 00000011)2

      紧接着我们开始异或运算 

                       11111111 11111111 11111111 11111101

                              ^       00000000 00000000 00000000 00000011


                        11111111 11111111 11111111 11111110

      (-3^3) 10 的补码为    (11111111 11111111 11111111 11111110)2

      因为符号位为1,所有是负数,所有

      (-3^3) 10 的反码为    (11111111 11111111 11111111 11111101)2

      (-3^3) 10 的原码为    (10000000 00000000 00000000 00000010)2

      所有(-3^3)=-2

     

     

      题目暂时就先这么多,因为我们要学会举一反三的思想。当然上面只不过是我们的理论知识,但是我们程序员需要有一种用代码检验真理的思想,我这里检验的代码用的是php,因为他的整型都是有符号的。

    下面附上php代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    /*运行环境Win7 64位旗舰版
     *服务器IIS7.5
     *代码语言PHP
     *编写日期2012-5-31
     *编写人:JimmyWu
     * */
     
    <html>
        <head>
            <title>位运算练习</title>
            <meta http-equiv="content-type" content="text/html;charset=utf-8" />
        </head>
    <body>
        <?php
            echo '整形的长度'.PHP_INT_SIZE.'<br />';
            //位运算
            echo '~2='.(~2).'<br />';
            echo '2&3='.(2&3).'<br />';
            echo '2|3='.(2|3).'<br />';
            echo '~-5='.(~-5).'<br />';
            echo '13&7='.(13&7).'<br />';
            echo '5|4='.(5|4).'<br />';
            echo '-3^3='.(-3^3).'<br />';
            echo '-1>>2 = '.(-1>>2).'<br />';
            echo '1>>2 = '.(1>>2).'<br />';
            echo '-1<<2 = '.(-1<<2).'<br />';
            echo '1<<2 = '.(1<<2).'<br />';
        ?>
    </body>
    </html>

      

  • 相关阅读:
    Zookeeper(1)---初识
    golang的一些零散笔记
    ELK使用过程中遇到的一些问题
    ECharts系列:玩转ECharts之常用图(折线、柱状、饼状、散点、关系、树)
    MySQL系列:Docker安装 MySQL提示错误:Access denied for user'root'@'localhost' (using password:yes)
    HTML+CSS系列:登录界面实现
    Apollo系列(二):ASP.NET Core 3.1使用分布式配置中心Apollo
    Apollo系列(一):分布式配置中心Apollo安装(Linux、Docker)
    为你的应用加上skywalking(链路监控)
    工作中,你是如何开始搭建一套容器云环境的呢?
  • 原文地址:https://www.cnblogs.com/mumue/p/2529169.html
Copyright © 2020-2023  润新知