🗒️位运算
2025-1-16
| 2025-2-26
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
创建时间
Jan 16, 2025 02:09 AM

什么是位运算

程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算说穿了,就是直接对整数在内存中的二进制位进行操作。比如,and 运算本来是一个逻辑运算符,但整数与整数之间也可以进行 and 运算。举个例子,6 的二进制是 11011 的二进制是 1011,那么6 and 11 的结果就是 2,它是二进制对应位进行逻辑运算的结果(0 表示 False, 1 表示 True, 空位都当 0 处理):
由于位运算直接对内存数据进行操作,不需要转成十进制,因此处理速度非常快。
符号
描述
运算规则
&
两个位都为 1 时,结果才为 1
|
两个位都为 0 时,结果才为 0
^
异或
两个位相同为 0,相异为 1
~
取反
0 变 1,1 变 0
<<
左移
各二进位全部左移若干位,高位丟弃,低位补 O
>>
右移
各二进位全部右移若干位,对无符号数,高位补 0,有符号数,各编译器处理方法不样,有的补符号位(算术右移),有的补0(逻辑右移)

XOR - 异或

异或:相同为 0,不同为 1。也可用「不进位加法」 来理解。
异或操作的一些特点:

实战常用的位运算操作

更为复杂的位运算操作

  1. 将x最右边的n位清零:x & ( ~0 << n )
  1. 获取x的第n位值(0 或者 1):( x >> n ) & 1
  1. 获取x的第n 位的幂值:x & ( 1 << ( n - 1 ))
  1. 仅将第n位置为1:x | ( 1 << n)
  1. 仅将第n位置为0:x & ( ~( 1 << n ))
  1. 将x最高位至第n位(含)清零:x & (( 1 << n) - 1 )
  1. 将第n位至第0位(含)清零:x & ( ~(( 1 << ( n + 1)) -

内建函数

GCC 中还有一些用于位运算的内建函数:
  1. int __builtin_ffs(int x) :返回 x 的二进制末尾最后一个 1 的位置,位置的编号从 1 开始(最低位编号为 1 )。当 x 为 0 时返回 0。
  1. int __builtin_clz(unsigned int x) :返回 x 的二进制的前导 0 的个数。当 x 为 0 时,结果未定义。
  1. int __builtin_ctz(unsigned int x) :返回 x 的二进制末尾连续 0 的个数。当 x 为 0 时,结果未定义。
  1. int __builtin_clrsb(int x) :当 x 的符号位为 0 时返回 x 的二进制的前导 0 的个数减一,否则返回 x 的二进制的前导 1 的个数减一
  1. int __builtin_popcount(unsigned int x) :返回 x 的二进制中 1 的个数。
  1. int __builtin_parity(unsigned int x) :判断 x 的二进制中 1 的个数的奇偶性。
这些函数都可以在函数名末尾添加 l 或 ll (如 __builtin_popcountll )来使参数类型变为 ( unsigned ) long 或 ( unsigned ) long long (返回值仍然是 int 类型)。
例如,我们有时候希望求出一个数以二为底的对数,如果不考虑 0 的特殊情况,就相当于这个数二进制的位数减去一 ,而一个数 n 的二进制表示的位数可以使用 32 - __builtin_clz(n) 表示,因此 31 - __builtin_clz(n) 就可以求出 n 以二为底的对数。
由于这些函数是内建函数,经过了编译器的高度优化,运行速度十分快(有些甚至只需要一条指令)。

📎 参考

notion image
notion image
notion image
notion image
notion image
notion image
notion image
notion image
notion image
  • Important
  • 3226. 使两个整数相等的位更改次数3370. 仅含置位位的最小整数
    Loading...