码迷,mamicode.com
首页 > 其他好文 > 详细

位运算

时间:2017-10-12 21:38:00      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:line   inline   范围   不同   处理   地址   swa   注意   运算   

  位运算包括 "~" , "&" , "|" , "^" , "<<" , ">>" 。

  "~"  的优先级比 "<<" , ">>" 高,"<<" , ">>" 的优先级比 "&" , "|" , "^" 高。

  值得一提的是 "~" 运算,它对每个二进制位进行取反,即原本从左侧找第 $x$ 个,现在从右侧找第 $x$ 个。对于无符号整数,按照 $0, 1, 2, ..., 32767, 32768, ..., 65535$ 存储,~x 等于该类型的最大值与 $x$ 的差值。对于有符号整数,按照 $0, 1, 2, ..., 32767, -32768, -32767, ..., -2, -1$ 存储,~x 等于 $-x-1$ 。

 

  如何交换两个数 $x, y$ ?

inline void Swap(int &x, int &y) {
        x = x + y;
        y = x - y;
        x = x - y;          
}

  对于 $0$ 和 $1$ 的交换,可以用异或运算代替上面的加法运算和减法运算。

  由于位运算具有位独立性,所以可以拓展到任意两个数的交换,即:

inline void Swap(int &x, int &y) {
        x ^= y ^= x ^= y;
}

  注意上述代码在 $x$ 和 $y$ 的地址相同的时候是行不通的。

 

  求 int 的最大值?

  考虑对 0u 取反,得到 unsigned int 的最大值,然后再除去 $1$ 个位,即: ~0u>>1 。

 

  判断 $x$ 的奇偶性?

  二进制的最后一位非 $0$ ,即: x & 1 。

 

  给定区间 $[l, r]$ ,求 $2 ^ l + 2 ^ {l+1} + ... + 2 ^ r$ ?

  求 $2 ^ 0 + 2 ^ 1 + 2 ^ 2 + ... + 2 ^ {r-l} = 2 ^ {r-l+1} - 1$ ,然后平移 $l$ 位,即: ((1 << r-l+1) - 1) << l 。

 

  把第 $k$ 位变成 $1$ : x |= (1 << k-1) 。

  把第 $k$ 位变成 $0$ : x &= (1 << k-1) 。

  把第 $k$ 位取反: x ^= (1 << k-1) 。

 

  取第 $k$ 位: x >> k-1 & 1 。

  取末 $k$ 位: x & ((1 << k) - 1) 。

  取 $[l, r]$ 这些位: x & ((1 << r-l+1) - 1) << l 。

 

  把区间 $[l, r]$ 变为 $0$ : x &= ~(((1 << r-l+1) - 1) << l) 。

  把区间 $[l, r]$ 变为 $1$ : x |= ((1 << r-l+1) - 1) << l 。

  把区间 $[l, r]$ 取反: x ^= ((1 << r-l+1) - 1) << l 。

 

  把右边连续的 $1$ 变为 $0$ :考虑把 $x$ 加 $1$ 之后,末尾的 $1$ 会变成 $0$ ,末尾的第 $1$ 个 $0$ 会变成 $1$ ,$x$ 与 $x+1$ 取交集之后,末尾的第 $1$ 个 $0$ 之后的位都为清零,即: x & x+1 。

  把右边第 $1$ 个 $0$ 变为 $1$ : x | x+1 。

  把右边连续的 $0$ 变为 $1$ :考虑把 $x$ 减 $1$ 之后,末尾的 $0$ 会变成 $1$ ,末尾的第 $1$ 个 $1$ 会变成 $0$ ,即: x & x-1 。

  取右边连续的 $1$ :加上 $1$ 后,最后的这些位都两两不同,异或为 $1$ ,个数为右边的 $1$ 的个数再多一位,所以: (x ^ x+1) >> 1 。

 

  求最低位 lowbit :想法是从右边开始逐位找,找到第 $1$ 个 $1$ 。

  也就是说,二进制表示长这样:    0101101100000    -- (1)

  对该数取反后,长这样:       1010010011111

  取反后加 $1$ ,长这样:          1010010100000    -- (2)

  比较(1)(2),比 lowbit 低的位置仍然是 $0$ ,lowbit 这位没有变,比 lowbit 高的位置取反,可知 lowbit 等于 x & (~x + 1) 。

  由于 ~x = -x - 1 ,所以 ~x + 1 = x ,所以 lowbit 等于 x & -x 。

 

  如何快速确定 int 范围内的正整数 $x$ 的二进制最低位是哪一位?

  预处理 p[2 ^ i] = i ,i = 0, 1, ..., 16 

  找到 $y$ 为 $x$ 的 lowbit ,若 $y < 2 ^ {16}$ ,那么直接查询 p[y] ,否则查询 p[y >> 16] + 16 。

位运算

标签:line   inline   范围   不同   处理   地址   swa   注意   运算   

原文地址:http://www.cnblogs.com/Sdchr/p/7657169.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!