zoukankan      html  css  js  c++  java
  • 001 位运算

    文章内容组成 = 大部分转载+自己思考

    文章内容构成 = 是什么+怎么用+有什么用+优/缺点

    转载部分http://www.cnblogs.com/911/archive/2008/05/20/1203477.html 

    一:位运算是什么?

    内存储存数据基本单位->字节(Byte),一个字节由8个位(bit)所组成。

    位运算是->是按二进制位进行的运算, C语言提供了6个位操作。

    运算符      描述
    &按位与  : 若两个相应的二进制位都为1,则该位的结果值为1,否则为0
    | 按位或  :  若两个相应的二进制位中只要有一个为1,该位的结果值为1
    ^按位异  : 若参加运算的两个二进制位值相同则为0,否则为1


    ~取反   : 是一元运算符,用来对一个二进制数按位取反,即将0变1,将1变0
    <<左移   :   将一个数的各二进制位全部左移N位,右补0
    >> 右移  :   将一个数的各二进制位全部右移N位,移到右端的低位被舍弃,对于无符号数,高位补0

    二:位运算怎么用?

    &运算

    3&5 过程如下:

    按位与运算过程:
     00000011(2)
    &00000101(2)
     00000001(2)

    |运算

    48|15 过程如下:

      00110000
    | 00001111
      00111111 

    ^运算

    0∧0=0,0∧1=1,1∧0=1, 1∧1=0

    ~运算
    将操作数各二进制位上的1变为0,0变为1。

    <<运算
    将一个数的各二进制位左移若干位,移动的位数由右操作数指定(右操作数必须是非负值),其右边空出的位用0填补,高位左移溢出则舍弃该高位。

    例如:将a的二进制数左移2位,右边空出的位补0,左边溢出的位舍弃。若

    a=15,即00001111(2),左移2位得00111100(2)。

    >>运算
    将一个数的各二进制位右移若干位,移动的位数由右操作数指定(右操作数必须是非负值),移到右端的低位被舍弃,对于无符号数,高位补0。

    a的值是八进制数113755: 
       a:1001011111101101 (用二进制形式表示)
       a>>1: 0100101111110110 (逻辑右移时)
       a>>1: 1100101111110110 (算术右移时)

    位运算赋值运算符

    位运算符与赋值运算符可以组成复合赋值运算符。
    例如: &=, |=, >>=, <<=, ∧=
    例:  a & = b相当于 a = a & b     a << =2相当于a = a << 2
            

    三:位运算有什么用

    按位&:

    作用:   (1) 目标数清零: 目标数 & 0 

          (2) 取目标数指定位: 目标数的指定位 & 指定位置为1    结果取出目标数的指定位

          (3) 保留目标数指定位: 目标数的指定位 & 指定位置为1  结果目标数保留指定位

    (1)清零          

    43 & 148过程
      00101011(2)
    &10010100(2)
      00000000(2)

    (2)取一个数中某些指定位
    整数a(2byte)想要取其低字节,将a与8个1按位与即可。
    a 00101100 10101100
    b 00000000 11111111
    c 00000000 10101100

    (3)保留指定位:
    数84想把从左边算起的第3,4,5,7,8位保留下来。
      01010100(2)
    &00111011(2)
      00010000(2)

    按位|:

    作用:  (1) 目标数指定位置为1: 目标数 | 指定位置位1 

    按位^:

    作用:  (1) 目标数指定位反转: 目标数 ^ 指定位置位1 

           (2) 目标数指定位保留原值: 目标数 ^ 指定位置位0

    按位~:

    作用:    (1) 目标数指定位反转: 目标数 ~ 指定位置位1

    具体应用:

    判断一个变量i 是奇数还是偶数

    if (i&1)

    printf("奇数 ");

    else

    printf("偶数 ");

    输入两个数,判断第一个数的第二数的位是不是1

    scanf("%d", &i);
    j = 2;
    j = (i & 2) >> 1;   //将第0位变成0,第一位保留本身

    printf("%d 第%d位是 %d ", i, 2, j);

    int类型赋初值为十六进制3085CDCFB,将7-15位置为101011011

    unsigned int i = 0x3085CDCFB;
    unsigned int j = 0;

    j = i & 0xFFFF007F; //将7到15位置为0

    j = i | 0xFFFFADFF; //将7到15通过按位或,变成:101011011
    printf("%d %d ", i, j);

    // Result Display
    140303611 -513

     

    输入一个数,实现其低四位反转

    scanf("%d", &i);
    j = i;
    i = i ^ 0xF;

    printf("%d 低四位反转变为 %d ", j, i);

    // Result Display
    1
    1 低四位反转变为 14
    2
    2 低四位反转变为 13
    3
    3 低四位反转变为 12
    4
    4 低四位反转变为 11

    交换a、b两个值,不用临时变量

    方法一:a = a ^ b;  b = a ^ b;  a = a ^ b;

    方法二:a = a + b;  b = a - b;  a = a - b;

     

    三:位运算优/缺点

    缺点:

    学习使用掌握比较麻烦

    使用范围有限(这些运算符只能用于整型操作数)

    位左右移动,可以溢出

    优点:

    位运算速度快

    有时使用位运算比较方便计算

  • 相关阅读:
    谈谈适配器模式
    最近面试的感想
    如何解决超链接访问后hover样式就不渲染
    单页面和多页面的网页差别比较(SPA)
    mongoDB发生服务特定错误: 100.
    win系统没有此电脑怎么办?
    u盘空间变小,少了好多空间
    VS Code 解决 因为在此系统上禁止运行脚本
    远离麻木的感觉
    瀑布布局(waterflall flow)实现
  • 原文地址:https://www.cnblogs.com/huafan/p/4367615.html
Copyright © 2011-2022 走看看