1. 基本介绍

1.1 按位逻辑运算

C++ 提供了按位与(&)、按位或(| )、按位异或(^)、取反(~)、左移(<<)、右移(>>)这 6 种位运算符。 这些运算符只能用于整型操作数,即只能用于带符号或无符号的 char、short、int 与 long 类型。

位逻辑运算符作用于位,并逐位执行操作。&、 | 和 ^ 的真值表如下所示:

p q p & q p | q p ^ q
0 0 0 0 0
0 1 0 1 1
1 1 1 1 0
1 0 0 1 1

整数举例如下(更多计算可以参考bitwise-operators.xlsx):

  十进制 二进制  
A 85 01010101  
B 13 00001101  
A & B 5 00000101  
A | B 93 01011101  
A ^ B 88 01011000  
~ A 170 10101010 假如A为8bit整数
~ A 65450 11111111 10101010 假如A为16bit整数
1.2 按位左移运算符(<<)和 按位右移运算符(>>)

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

在高位没有1的情况下,左移1位相当于该数乘以2,左移3位相当于该数乘以232^3。例如: 15 << 3 = 120。

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

#include <iostream>
using namespace std;

int main() {
  //-------------------------------------------//
  //          按位左移运算符示例               //
  //-------------------------------------------//
  unsigned short int a = 13; // 0000 1101
  a = (a << 1);
  cout << a << endl; //左移一位

  unsigned short int b = 32781; // 1000 0000 0000 1101
  b = (b << 1);
  cout << b << endl; //左移一位

  //-------------------------------------------//
  //          按位右移运算符示例               //
  //-------------------------------------------//
  unsigned short int c = 13; // 0000 1101
  unsigned short int d = (c >> 3); //按位右移3位
  cout << d << endl;        
  cout << (c >> 3) << endl; //按位右移3位
  
  cout << (15 >> 2) << endl; //按位右移2位

  return 0;
}
//********** 请写出该程序的输出 ************

2. 编程
  1. csp-j-20-1 优秀的拆分

参考实现:

#include <iostream>

using namespace std;

int main() {
  int n;
  cin >> n;
  if (n % 2) {
    cout << "-1" << endl;
    return 0;
  }

  bool is_first = true;
  for (int i = 31; i >= 0; i--) {
    if (n >> i & 1) { //看看那一位是否为1。注意和1做“位与”

      if (!is_first) { //不是第一个输出的数
        cout << " ";
        is_first = false;
      }

      cout << (1 << i); //将1按位左移i位,即二进制第i位的整数值。
    }
  }
  cout << endl;

  return 0;
}