位运算符

位运算符作用于位,并逐位执行操作

建议动纸笔手算便于理解

按位运算

运算符 描述
& 按位与操作,按二进制位进行”与”运算
| 按位或运算符,按二进制位进行”或”运算
~ 取反运算符,按二进制位进行”取反”运算
^ 异或运算符,按二进制位进行”异或”运算
&
  • 对比a与b的二进制数,当重叠部分皆是1时则为1,当任其一位有差异或皆为0则为0,超出部分忽略按0处理

  • 用于处理让某一位或某些位为0: x & 254让最后一位为0

  • 例如53 & 37

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    先将两个数的二进制换算出来,然后进行位与运算
    53的二进制数是: 1 1 0 1 0 1
    37的二进制数是: 1 0 0 1 0 1
    ⇩_____⇩___⇩
    1 0 0 1 0 1 // 相与后的结果
    ___________
    // 二进制转十进制,从右向左计算
    (1*2^0)+(0*2^1)+(1*2^2)+(0*2^3)+(0*2^4)+(1*2^5)
    _______________________________________________
    1 + 0 + 4 + 0 + 0 + 32 = 37

|
  • 对比a与b的二进制数,当重叠部分皆是1或任其一位为1则为1,都是0则为0

  • 超出部分是1则按1算

  • 例如23 | 49

  • 常用于让一位或几个位为1: x | 1 如论x是0还是1,或1后都是1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    先将两个数的二进制换算出来,然后进行位或运算
    53的二进制数是: 1 0 1 1 1
    37的二进制数是: 1 1 0 0 0 1
    ⇩_⇩___⇩_⇩_⇩
    1 1 0 1 1 1 // 相或后的结果
    ___________
    // 二进制转十进制,从右向左计算
    (1*2^0)+(1*2^1)+(1*2^2)+(0*2^3)+(1*2^4)+(1*2^5)
    _______________________________________________
    1 + 2 + 4 + 0 + 16 + 32 = 55

~
  • 对于a的二进制数来做取反的输出,即1变成0,0变成1

  • 例如~88

  • ~0 –> -1

  • ~70 –> -71

    1
    2
    3
    4
    5
    6
    计算88的二进制数,让其0变1,1变0
    88的二进制数是 0 1 0 1 1 0 0 0
    做取反 1 0 1 0 0 1 1 1

    其中有一位是二进制数的补码形式
    其最终结果就是-89
^
  • 对于a与b的二进制数做按位异或的运算,如果a和b两个位相等,结果为0,否则不相等结果为1

  • 如果a与b 的值相等,那么结果为0

  • 对同一个变量用同一个值异或两次,将回到原值

  • a ^ b ^ b --> a

  • 例如32^11

    1
    2
    3
    4
    5
    6
    7
    8
    计算32和11的二进制数
    32的二进制数: 0 0 1 0 0 0 0 0
    11的二进制数: 0 0 0 0 1 0 1 1
    做异或: ⇩ ⇩ ⇩ ⇩
    0 0 1 0 1 0 1 1
    (1*2^0)+(1*2^1)+(0*2^2)+(1*2^3)+(0*2^4)+(1*2^5)+(0*2^6)+(0*2^7)
    _________________________________________________________________
    1 + 2 + 0 + 8 + 0 + 32 + 0 + 0 = 43

移位运算

运算符 描述
<< 二进制左移运算符,将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)
>> 二进制右移运算符,将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃

没有移位负数这一说!

<<
  • a << b将a的二进制数向左移动b个位置,右边多出部分补0

  • 所有小于int的类型,移位以int的方式来做,其结果是int类型

  • a << 1 == a *= 2, a << n == a *= 2^n

    • 例如a = 5; a << 2 == a = 5*4
  • 按照二进制计算,例如27 << 4

    1
    2
    3
    4
    5
    6
    7
    8
    计算27的二进制数
    27的二进制数: 0 0 0 1 1 0 1 1
    |
    左移四位变成 0 0 0 1 1 0 1 1 0 0 0 0
    计算出左移后的值
    (0*2^0)+(0*2^1)+(0*2^3)+(1*2^4)+(1*2^5)+(0*2^6)+(1*2^7)+(1*2^8)
    _________________________________________________________________
    256 + 128 + 32 + 16 = 432

>>
  • a >> b将a的二进制数向右移动b个位置,右边超出部分丢弃

  • 所有小于int的类型,移位以int的方式来做,其结果是int类型

  • 对于Unsigned类型,左边填入0,对于signed类型,左边填入原来的最高位(保持符号不变)

  • a >> 1 == a /= 2, a >> n == x /= 2^n

    • 例如a = 20; a >> 3 == a = 20/8
  • 按照二进制计算,例如37 >> 2

    1
    2
    3
    4
    5
    6
    7
    8
    计算37的二进制数
    37的二进制数: 0 0 1 0 0 1 0 1
    |
    右移两位变成 0 0 0 0 1 0 0 1
    计算出右移后的值
    (1*2^0)+(0*2^1)+(0*2^3)+(1*2^4)
    _______________________________
    1 + 0 + 0 + 8 = 9

评论