Lecture 3 Bit Hacks

本文介绍了Lecture3 BitHacks中的关键概念,包括二进制表示、无符号/有符号整数转换、位操作技巧(如置位、清零、取反、提取和设置位字段)、高效交换、查找最小值和模块加法等。通过实例演示如何利用位运算避免临时变量和分支,适合深入理解计算机底层和编程优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Lecture 3 Bit Hacks

课程内容

备注:以下并未列出课程全部内容,只是将我理解并觉得用处比较多的地方列了出来。

Binary Representation

虽然大家早已经知道了二进制原码、反码、补码的意思,不过这里提供了另一种解释方法。很有意思。这里记录下来。
x={xw−1xw2...x0}{x=\{x_{w-1}x_{w_2}...x_0\}}x={xw1xw2...x0}是一个w位的无符号整数,二进制表示为:
x=Σk=0w−1xk2k x=\Sigma^{w-1}_{k=0}x_k2^k x=Σk=0w1xk2k
有符号整数(补码)的表示是:
x=(Σk=0w−2xk2k)−xw−12w−1 x=(\Sigma^{w-2}_{k=0}x_k2^k)-x_{w-1}2^{w-1} x=(Σk=0w2xk2k)xw12w1
其中,xw−1{x_{w-1}}xw1是符号位。

Set the kth Bit

  • 【问题】将x的第k位设为1.
  • 【方法】左移、或。
y = x | (1 << k)
  • 【备注】1 << k就是第k位的mask(掩码)。

Clear the kth Bit

  • 【问题】将x的第k位设为清0.
  • 【方法】左移、取反、与。
y = x & ~(1 << k)

Toggle the kth Bit

  • 【问题】将x的第k位取反。
  • 【方法】左移、或。
y = x ^ (1 << k)

Extract a Bit Field

  • 【问题】从x中提取第shift位
  • 【方法】掩码、右移。
(x & mask) >> shift

Set a Bit Field

  • 【问题】将x的shift位设为y。
  • 【方法】掩码取反、或上右移之后的值。
x = (x & ~mask) | (y << shift)

No-Temp Swap

  • 【问题】不用临时变量,将x、y交换。
    一般有:
t = x;
x = y;
y = t;

使用二进制方式:

x = x ^ y;
y = x ^ y;
x = x ^ y;
  • 【原理】xor的特性:(x ^ y) ^ y = x
  • 【性能】虽然没有创建临时变量,但是在现代CPU上,不能很好的利用指令级并行(Instruction-Level Parallelism, ILP)。

No-Branch Minimum

  • 【问题】找到x、y中的最小值。
r = y ^ ((x ^ y) & -(x < y))
  • 【备注】编译器可能会做得更好。

Modular Addition

  • 【问题】计算(x + y) mod n
// 基础版
r = (x + y) % n;

// 没有除法,无法预测的分支。
z = x + y;
r = (z < n) ? z : z - n;

// use bit hack
z = x + y;
r = z - (n & -(z >= n));

Least-Significant 1

  • 【问题】计算x中最低有效位中的1的掩码。
r = x & (-x)

Population Count

  • 【问题】计算x中的1的个数。
// 基础版
for (r = 0; x != 0; ++r)
	x &= x - 1;
  • 【注意】最坏情况下,要循环x的位数次。
  • 查表的方法
static const int count[256] = 
{0, 1, 1, 2, 1, 2, 2, 3, 1, ..., 8};
for (int r = 0; x != 0; x >>= 8)
	r += count[x & 0xFF];

表中的数据是256个,记录了每个数(数组的index)对应的1的个数。

  • 【相关指令】现代CPU上,统计1的数量的函数,都已经有了相应的指令,比任何人写出的代码都要更快。如在GCC中,有函数:
int __builtin_popcount(unsigned int x);

TODO

英语学习

  • ^:读作“caret sign”。
  • ~:读作“tilde”。
  • caveat:警戒、告诫。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值