不落辰

知不可乎骤得,托遗响于悲风

0%

datalab

位运算 tips

注意事项及技巧

  • A^B = AB’ + A’B

  • 注意符号扩展!!!

  • 注意有符号数右移时的符号位扩展

    1
    2
    3
    4
    5
    6
    7
    8
    int x = -1;
    cout<<x<<endl; // 1111111...1111
    cout<<(x>>31)<<endl; // 1111111...1111
    // 发生符号位扩展,因为x为有符号数,且符号位为1。故右移时用1填充
    cout<<((x>>31)&1)<<endl; // 00000000...0001
    -1
    -1
    1
  • 两个int立即数异或出的结果立即数,也会进行符号扩展。

    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
    31
    32
        int x = -2;
    // int y = -5;
    int y = 5;
    cout<<x<<" "<<y<<endl;

    int bitX = x>>31;
    int bitY = y>>31;
    cout<<bitX<<" "<<bitY<<endl;
    cout<<(unsigned) bitX <<" "<<(unsigned )bitY<<endl;
    cout<<"====="<<endl;
    int check1 = (x>>31) ^ (y>>31); // 有符号数 异或出1,会进行符号扩展。在赋值给check1之前,就扩展为111111...1111。check1于是为-1:1111..111111
    cout<<check1<<" " <<(unsigned )check1<<endl;

    int check2 = bitX ^ bitY;
    cout<<check2<<" "<<(unsigned )check2<<endl;
    return 0;

    y=-5
    -2 -5
    -1 -1
    4294967295 4294967295
    =====
    0 0
    0 0

    y=5
    -2 5
    -1 0
    4294967295 0
    =====
    -1 4294967295
    -1 4294967295
  • 获得符号位的正确操作

    1
    2
    3
    int x_sign = x>>31&1;     //  获取x最高符号位,并将其放到0位
    int y_sign = y>>31&1; // 获取y最高符号位,并将其放到0位
    int sign_xor = x_sign ^ y_sign; // x和y符号位是否相同 相同为0,不同为1。
  • 如何获取一个 m位二进制数(称为待分解数)的低x位
    • 先定义一个 m位 unsigned 全f 掩码
    • 然后利用unsigned特性(右移左侧补0)右移(m-x)位,然后得到x位全f掩码(高m-x位均为0)
    • 将待分解数与x位全f掩码相&,
    • 得到待分解数的低x位。
      1
      2
      3
      4
      unsigned long mask = 0xffffffffffffffff;
      unsigned long xxxMask = mask >> (m-x); // 由于mask为unsigned 故左侧补0
      unsigned long xxx = xxx & numberToDo;
      printf("mask = %lx\txxxMask=%lx\txxx=%ld\n",mask,xxxMask,xxx);
    • 或者也可以通过先左移(m-x),再右移(m-x)。也是要利用unsigned无符号扩展。