位运算的一些性质

记号

位运算中的集合符号

定义x ⫅ \subseteqq y表示x的二进制位每一位都小于或等于y的对应位。
对于x ⊆ \subseteq y有同样的意思。
x ⊂ \sub y表示x ⊆ \subseteq y且x≠y。

与运算

定义如下形式表示整数x、y做位与运算:

  • x a n d and and y
  • x&y
  • x∩y
  • x b i t a n d bitand bitand y

或运算

定义如下形式表示整数x、y做位或运算:

  • x o r or or y
  • x|y
  • x∪y
  • x b i t o r bitor bitor y

按位取反

定义如下形式表示整数x按位取反:

  • n o t not not x
  • ~x
  • x ‾ \overline{x} x

异或运算

定义如下形式表示整数x、y做位异或运算:

  • x x o r xor xor y
  • x^y
  • x ⊕ \oplus y

与运算对应交集,或运算对应并集,而取反运算对应补集。
事实上,异或运算对应集合运算中的“对称差”,有时也用 A △ B A△B AB表示。

左移与右移运算

定义如下形式表示整数x、y做左移运算:

  • x<<y

定义如下形式表示整数x、y做右移运算

  • x>>y

位运算性质

交换律、结合律、幂等律

位与、位或、位异或运算具有交换律和结合律。

  • x∩y=y∩x,x∩(y∩z)=(x∩y)∩z
    所有与运算数,在同一位上有一个为0,这一位最终结果就是0;
  • x∪y=y∪x,x∪(y∪z)=(x∪y)∪z
    所有或运算数,在同一位上有一个为1,这一位最终结果就是1;
  • x ⊕ \oplus y=y ⊕ \oplus x,x ⊕ \oplus (y ⊕ \oplus z)=(x ⊕ \oplus y) ⊕ \oplus z
    所有异或运算数,在同一位上1的个数为奇数,这一位最终结果就是奇数。

事实上,由于位运算各个数位之间是独立的,所以只需要证明同一个二进制位中定理成立,就可以证明定理成立。
因此所有定理都可以通过分情况讨论得出,因此下面就不证明了,直接给出结论。

此外:

  • x∩x=x
  • x∪x=x
  • x ⊕ \oplus x=0
    显然.

分配律

位运算满足对应的集合运算分配律:

  • x∩(y∪z)=(x∩y)∪(x∩z)
  • x∪(y∩z)=(x∪y)∩(x∪z)

异或运算和与运算也满足分配律:

  • x∩(y ⊕ \oplus z)=(x∩y) ⊕ \oplus (x∩z)
    有的地方称这个为“分段律”

一个错误的例子:
x ⊕ \oplus (y∩z)=(x ⊕ \oplus y)∩(x ⊕ \oplus z)

这表明与运算、异或运算可以拆开。

吸收律

位运算满足对应的集合运算的吸收律。

  • x∪(x∩y)=x
  • x∩(x∪y)=x

有的地方说位异或运算满足吸收律,例如:A∩(A ⊕ \oplus B)=A或者A∪(A ⊕ \oplus B)=B。
但这事实上是错的,位异或运算不满足吸收律。

其他定律

位运算还满足其他一些对应的集合运算定律,例如对合律: x ‾ ‾ = x \overline{\overline{x}}=x x=x
其他过于简单的定律不再赘述。

位运算事实上还满足对应集合运算的德·摩根定律:

  • x ∩ y ‾ = x ‾ ∪ y ‾ \overline{x ∩ y}=\overline{x}∪\overline{y} xy=xy
  • x ∪ y ‾ = x ‾ ∩ y ‾ \overline{x ∪ y}=\overline{x}∩\overline{y} xy=xy

上述所有二元定律的多元形式,位运算有对应的满足。

异或运算事实上还满足:
x ⊕ \oplus y=(x∩y) ⊕ \oplus (x∪y)
由于异或运算、或运算拆不开,因此该公式似乎没有多元形式。

lowbit、highbit

lowbit(x)表示x的二进制表示中最低位的1代表的值。
如:lowbit(4)=4,lowbit(3)=1

  • l o w b i t ( x ) = x ∩ − x lowbit(x)=x∩-x lowbit(x)=xx
    也就是lowbit(x)=x&-x

highbit(x)表示x的二进制表示中最高位的1代表的值。
如:highbit(5)=4

highbit没什么太好的求法,不过主流来说有这么两种方法:

  1. 大致原理就是作差:
    在这里插入图片描述
    2.还可以用builtin函数:
    在这里插入图片描述
    不过注意不同类型builtin函数名不一样。

还有一种做法是不断地减去lowbit,不过这个太慢了,不考虑。

事实上还有:

  • x∩-x=lowbit(x)
  • x∪-x=-lowbit(x)
  • x ⊕ \oplus -x=-lowbit(x)<<1
    x可以是负数。

位运算技巧

异或和

归纳法易证:
⨁ i = 1 n i = { n ≡ 0 ( m o d   4 ) : n n ≡ 1 ( m o d   4 ) : 1 n ≡ 2 ( m o d   4 ) : n + 1 n ≡ 3 ( m o d   4 ) : 0 \bigoplus_{i=1}^ni= \left\{\begin{matrix} n \equiv 0 (mod \: 4) :n \\ n \equiv 1 (mod \: 4):1\\ n \equiv 2 (mod \: 4):n+1 \\ n \equiv 3 (mod \:4):0 \end{matrix}\right. i=1ni= n0(mod4):nn1(mod4):1n2(mod4):n+1n3(mod4):0

与和、或和按位判一下就行。

__builtin函数

__builtin函数用于位运算,在algorithm库内。
__builtin函数虽然不是c++标准,但是比赛的GNU还是支持这个东西的。

  • 统计前导零(count leading zero):__builtin_clz(x)
  • 统计后缀零(count trailing zero):__builtin_ctz(x)
  • 统计二进制位中1的个数(popcount):__builtin_popcount(x)
  • 快速开平方:__builtin_sqrtl(x)
    参数是long double
  • 快速开平方:__builtin_sqrt(x)
    参数是double
  • 快速开平方:__builtin_sqrtf(x)
    参数是float
    因为启用了硬件加速,可能比直接sqrt快很多。
    也可能只有一个递归的差距,毕竟:

在这里插入图片描述

其他一些用处不是很大的__builtin函数

注意__builtin函数在longlong和long有其对应形式:
如前导零函数:
unsigned:__builtin_clz(x)
unsigned long:__builtin_clzl(x)
unsigned long long:__builtin_clzll(x)

后记

于是皆大欢喜。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值