c语言基础-位运算11

来源:互联网 发布:js求字符串字节长度 编辑:程序博客网 时间:2024/06/05 19:40

 1.位运算.

  指的是1个二进制数据的每一位来参与运算.

  位运算的前提: 是这个数必须是1个二进制.

 

   注意:

   1).参与位运算的二进制数据必须是补码形式.

   2).位运算的结果也是二进制的补码形式.

 

 

 2.按位与: &

    

   参与按位与的两个二进制数.如果都为1那么结果就为1 只要有1位为0那么结果就为0.

 

    3 & 2;

   1步骤:先得到两个数的二进制补码形式.

 

    3的补码: 00000000 00000000 00000000 00000011

    2的补码: 00000000 00000000 00000000 00000010

    ----------------------------------------------

            00000000 00000000 00000000 00000010   2

 

    

    -3 & 4;

    

    -3的原码:10000000 00000000 00000000 00000011

    -3的反码:11111111 11111111 11111111 11111100

    -3的补码:11111111 11111111 11111111 11111101

    4的补码: 00000000 00000000 00000000 00000100

    ----------------------------------------------

            00000000 00000000 00000000 00000100

 

 

    -3 & -4;

    

    -4的原码: 10000000 00000000 00000000 00000100

    -4的反码: 11111111 11111111 11111111 11111011

 

 

 

    -3的补码:11111111 11111111 11111111 11111101

    -4的补码:11111111 11111111 11111111 11111100

    ---------------------------------------------

            11111111 11111111 11111111 11111100

   结果是补码: 现将其还原为反码

 

      反码:      11111111 11111111 11111111 11111011

      原码:      10000000 00000000 00000000 00000100

 

 

    ----------

 

    

   任何数按位与1的结果是:是这个数的最低位.

 

    10 & 1 

    xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxx0

    00000000 00000000 00000000 00000001

    ------------------------------------

    00000000 00000000 00000000 00000000

 

 

   偶数的最低位一定是0. 奇数的最低为一定是1

   所以,如果要判断这个数是奇数还是偶数 只要用这个数按位与1就可以了.

    

   如果结果为1 那么就是奇数如果结果为0 那么结果就是偶数.

 

 

    int num = 10;

    if((num & 1) == 0)

    {

        偶数.

    }

    else

    {

        奇数.

    }

 

 

 3. 按位或. |

 

   参与按位或的二进制数据 只要有1位是1那么结果就为只有当两位都是0的时候结果才为0

 

    3 | 2;

 

     3的补码: 00000000 00000000 00000000 00000011

     2的补码: 00000000 00000000 00000000 00000010

     ----------------------------------------------

             00000000 00000000 00000000 00000011

 

 

    -3 | 4

 

     -3的补码:11111111 11111111 11111111 11111101

     4的补码: 00000000 00000000 00000000 00000100

        -----------------------------------------

             11111111 11111111 11111111 11111101

    结果是1个负数.

        反码: 11111111 11111111 11111111 11111100

        原码: 10000000 00000000 00000000 00000011

 

 

     -3 | -4

     -3的补码:11111111 11111111 11111111 11111101

     -4的补码:11111111 11111111 11111111 11111100

     ---------------------------------------------

             11111111 11111111 11111111 11111101

 

 

 

 

 4. 按位取反: ~

   单目运算符. 将这个二进制数的每一位取反.

 

    ~3;

 

    3的补码: 00000000 00000000 00000000 00000011

            11111111 11111111 11111111 11111100补码

            11111111 11111111 11111111 11111011反码

            10000000 00000000 00000000 00000100原码

            

 

 

 

 5. 按位异或: ^    shift + 6

 

   参与按位异或的二进制数据的位 如果相同则为0不同为1.

 

    

    3 ^ 2;

 

    00000000 00000000 00000000 00000011   3的补码

    00000000 00000000 00000000 00000010   2的补码

    --------------------------------------

    00000000 00000000 00000000 00000001   1

 

 

    

   交换两个变量的值可以用异或运算.

 

 

    int a = 3;

    int b = 2;

 

    a = a ^ b;  a = 1

    b = a ^ b;  b = 3

    a = a ^ b;  b = 2

 

    1 ^ 2

    00000000 00000000 00000000 00000001

    00000000 00000000 00000000 00000010

    ------------------------------------

    00000000 00000000 00000000 00000011  3

 

 

 

    00000000 00000000 00000000 00000001

    00000000 00000000 00000000 00000011

    -------------------------------------

    00000000 00000000 00000000 00000010  2

 

 

 

 6. 按位左移运算. <<

 

   参与按位左移运算的二进制数据. 向左移动指定的位数.低位不够补0 高位溢出就丢弃.

 

    3 << 2;

 

    00000000 00000000 00000000 00000011

    000000 00000000 00000000 0000001100

    

    12

 

    注意:

    1).左移运算有可能会改变其正负性.

    2).1个数左移n位,相当于将这个数乘以 2n次方.

 

        3 << 2    3乘以22次方.

    

       16 << 3;   16 * 8  128

 

       5 * 16 = ????

 

       5 << 4

 

 

 

 7. 按位右移. >>

 

   参与按位右移的二进制数据.向右移动指定的位数.低位溢出丢弃,高位补符号位.

 

    3 >> 2;

 

    00000000 00000000 00000000 00000011

    0000000000 00000000 00000000 000000

 

 

    16 >> 2;

 

    00000000 00000000 00000000 00010000

      00000000 00000000 00000000 000100

 

    -16 >> 3

 

    10000000 00000000 00000000 00010000

    11111111 11111111 11111111 11101111

    11111111 11111111 11111111 11110000

 

    11111111111 11111111 11111111 11110

    11111111111 11111111 11111111 11101反码

    10000000000 00000000 00000000 00010

 

 

    注意.

    1).右移运算不会改变正负性.

    2). 1个数按位右移n.相当于这个数除以2n次方.

 

    100 >> 2  === 100 / 4

    100 / 4