位运算

作者: 王小宝wy | 来源:发表于2016-11-24 09:46 被阅读0次

原码,反码,补码

原码

  1. 正数的原码就是其二进制本身
  2. 负数的原码是把对应的正数的原码最高位改为1

反码

  1. 正数的反码就是其二进制原码本身
  2. 负数的反码是在其原码的基础上,符号位不变,其余各位取反

补码

  1. 正数的补码就是其二进制原码本身
  2. 负数的补码是在其反码的基础上加1,** -1的补码是11111111, 所以当一个数减1的时候,可以直接对其二进制数加1111111**

位运算小技巧

NOTE: 位运算只能运用在整数上

判断奇偶

只要根据末位是0还是1来决定,末位为0就是偶数,末位为1就是奇数,因此可以这样写

bool is_odd(int n) { 
    if ( n & 1 == 0) {
        return true; 
    }
    return false;
}

交换两数

//位操作的交换两数
void swap(int &a, int &b) { 
    a = a ^ b; 
    b = b ^ a; 
    a = a ^ b;
}
  • b = b ^ a这一句根据上一句可以替换为b = b ^ (a ^ b),由于^(异或操作)满足交换律, b = b ^ a ^ b等价于b = b ^ b ^ a,对于异或操作来说,一个整数和自己异或永远等于0,  而一个数与0进行异或数值仍然不变, 所以此时等价于b = a
  • 第三句a = a ^ b,由于第二句等价于b = a且第一句a = a ^ b所以第三句可以等价于a = a ^ b ^ a,又可以等价于a = b,即a被赋予b的值

正负变换

11的二进制为000 01011 , 进行取反 --> 1111 0100, 加1 --> 1111 0101(-11)同理,-11的二进制为1111 0101,取反 --> 0000 1010,加1 --> 0000 1011(11)

int reverse_signal(int n) { 
    return ~n + 1;
}

求绝对值

  1. 先移位来取符号位, int i = n >> 31, 如果n为整数则i=0,n为负数则i=-1> 因为int型整数一般是4个字节,共32位,最高位为符号位,所以右移31位可以得到符号位> NOTE:符号位为1即负数的二进制,每右移一位,高位补的是1
  2. 对于任何数,与0异或保持不变,与-1即0xFFFFFFFF异或相当于取反,因此,n与i异或后再减i(因为i不是为0就是-1,而减去-1即加1)也可以得到绝对值> 二进制转十六进制:-1的二进制为32个1, 转成十六进制的话,每四位先计算出对应的十进制
//第一种方法
int abs(int n) {
    int i = n >> 31; 
    return i == -1 ? (~n + 1) : n;
}
//第二种方法
int abs(int n) {
    int i = n >> 31; 
    return (a ^ i) - i;
}

高低位交换

假设一个16位无符号整数的二进制为:1000011011011000,经过高低位变换后则为11011000 10000110.无符号左移低位补0,右移高位补0,因此将1000011011011000 这个数先右移8位为0000000010000110得到高位,再将10000011011011000左移8位为11011000 00000000即得到低位,再将两个数相或就可以得到高低位变换后的数字

int low_high_transit(int n) { 
    return (n >> 8) | (n << 8)
}

二进制逆序

//16位二进制
int reverse_binary(int &n) { 
  n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); 
  n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2);
  n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); 
  n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); 
  return n;
}

计算32位二进制有几个位是1

//32位二进制,如果要计算16位则0x55555555变为0x5555,依次类推,且没有最后一步
int count_bit(int &n) { 
    n = (n & 0x55555555) + ((n & 0xAAAAAAAA) >> 1); 
    n = (n & 0x33333333) + ((n & 0xCCCCCCCC) >> 2); 
    n = (n & 0x0F0F0F0F) + ((n & 0xF0F0F0F0) >> 4); 
    n = (n & 0x00FF00FF) + ((n & 0xFF00FF00) >> 8); 
    n = (n & 0x0000FFFF) + ((n & 0FFFF0000)) >> 16);
}

相关文章

  • 3、小众运算符の大课堂(一)

    较为简单の位运算符: & 位与运算| 位或运算^ 位异或运算~ 位取反运算 举例: 要做位运算,首先要把数据转...

  • 位运算及其应用

    内容概要: 位运算基本操作 基于位运算的状态压缩 位运算经典应用 位运算解N皇后问题 位运算 符号描述规则&与1&...

  • 位运算及用位运算实现权限控制

    请自行补习位运算相关知识 位运算 位运算示例 权限控制

  • 开发基础随笔之位运算符(Bitwise Operators)

    位运算符,属于算术运算符 按位逻辑运算符: 位移运算符: 位运算符的运算数只能是整数 位移运算符:按位左移 a<<...

  • 强大的位运算符

    位取反运算符 位取反运算符(~)是对所有位的数字进行取反操作位取反运算符.png 位与运算符 位与运算符(&)可以...

  • 位运算

    位运算 1. &:按位与 规律:一假则假任何位上的数和1相&得到的结果还是那个数 2. |:按位或 规律:一真则真...

  • 位运算

    https://leetcode.com/problems/gray-code/description/这个位运算...

  • 位运算

    位运算符比一般的算术运算符速度要快,而且可以实现一些算术运算符不能实现的功能。如果要开发高效率程序,位运算符是必不...

  • 位运算

    1.不用加减乘除做加法 解法:分为三步①各位相加不进位,即先按位异或;②做进位,按位与并左移位;③结果相加,直至没...

  • 位运算

    位运算不仅可以简化某些复杂的操作,而且具有更快的计算速度。典型的应用就是除法,交换两个数值,以及在一个数组中寻找只...

网友评论

      本文标题:位运算

      本文链接:https://www.haomeiwen.com/subject/fjrbpttx.html