证明:a%b == a&(b-1)

在底层实现和性能优化(如 HashMap 的实现原理之索引计算)中,有这么一个等式经常被使用:

a % b == a & (b - 1)

可以认为这是一个高效取模运算的技巧,下面是该公式的使用条件限制和标准证明

描述

对于任意非负整数 a 和任意正整数 b,如果 b 是 2 的整数次幂,那么 ab 取模的结果等价于 a(b - 1) 进行 按位与(&) 运算的结果

形式化定义:

  • a 为一个整数,且 a ≥ 0
  • b 为一个整数,且 b = 2^n,其中 n 为一个非负整数 (n ≥ 0)
  • 则以下等式恒成立:
    a % b == a & (b - 1)

证明

为了证明这个定理,我们需要从二进制表示的角度来理解取模运算和按位与运算

1. 分析 bb - 1 的二进制形式

  • 因为 b 是 2 的 n 次幂 (b = 2^n,其中 n ≥ 1 以使问题有意义),其二进制表示为一个 1 后面跟着 n0
    • 例如,如果 b = 16 (2^4),其二进制为 10000
  • 那么 b - 1 的二进制表示则是由 n1 组成
    • 例如,如果 b = 16,那么 b - 1 = 15,其二进制为 01111

所以,b - 1 是一个低位掩码,它的低 n 位全部为 1,而所有更高位都为 0

2. 分析取模运算 a % b

  • 取模运算 a % b 的结果是 a 除以 b 的余数 r根据除法原理,任何非负整数 a 都可以表示为:
    a = q * b + r
    其中 q 是商,r 是余数,且 0 ≤ r < b
  • b = 2^n 代入,我们得到:
    a = q * 2^n + r
  • 在二进制中,乘以 2^n 相当于左移 n 位这意味着 q * 2^n 这个数的二进制表示中,其低 n 位必然全部为 0
  • 因为 0 ≤ r < b,即 0 ≤ r < 2^n,所以余数 r 的二进制表示最多只需要 n
  • 当我们将 q * 2^nr 相加时,由于 q * 2^n 的低 n 位都是 0,所以相加的结果 a 的低 n 位就完全由 r 决定换句话说,a 的低 n 位组成的数就是余数 r

3. 分析按位与运算 a & (b - 1)

  • 我们已经知道 b - 1 是一个低 n 位全为 1,高位全为 0 的掩码
  • a(b - 1) 进行按位与运算时:
    • a 的高位部分与 (b - 1) 的高位 0 相与,结果全部为 0
    • a 的低 n 位部分与 (b - 1) 的低 n1 相与,结果保持 a 的低 n 位不变
  • 因此,a & (b - 1) 的运算结果就是提取出 a 的低 n 位所代表的数值

4. 结论

  • 从第 2 步我们得出:a % b 的结果是 a 的低 n 位所代表的数值
  • 从第 3 步我们得出:a & (b - 1) 的结果也是 a 的低 n 位所代表的数值

因为两者都等于 a 的低 n 位所代表的数值,所以 a % b == a & (b - 1)

证明完毕


举例验证:

  • a = 21b = 16
  • a 的二进制:10101
  • b 的二进制:10000 (b = 2^4, n=4)
  • b - 1 的二进制:01111

取模运算:
21 % 16 = 5

按位与运算:

  10101  (a = 21)
& 01111  (b - 1 = 15)
---------
  00101  (结果为 5)

两者结果相等,定理成立

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值