zoukankan      html  css  js  c++  java
  • 位运算(转)

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

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

    ~           取反运算符,如果运算位为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>

      

  • 相关阅读:
    监控里的主码流和子码流是什么意思
    监控硬盘容量计算
    一个能让你了解所有函数调用顺序的Android库
    电工选线
    oracle linux dtrace
    list all of the Oracle 12c hidden undocumented parameters
    Oracle Extended Tracing
    window 驱动开发
    win7 x64 dtrace
    How to Use Dtrace Tracing Ruby Executing
  • 原文地址:https://www.cnblogs.com/mumue/p/2529169.html
Copyright © 2011-2022 走看看