先说一点理论。
现在我们可以理解这个技巧了,假设 unsigned int 有 32 位:它“递归”地计算奇偶校验,首先将两位(两个相邻位)的子集中的位分组,然后执行奇偶校验在那些子集上。然后它通过使用刚刚计算的 2 位子集的奇偶校验来检查下一个更大的 4 位集合的奇偶校验。然后继续使用 8 位和 16 位子集。
让我们以图形方式查看它(为了清楚起见,在最不重要的位上):
y = x ^ (x >> 1)
x: b7 b6 b5 b4 b3 b2 b1 b0
x>>1: b8 b7 b6 b5 b4 b3 b2 b1
y=: P8-7 P7-6 P6-5 P5-4 P4-3 P3-2 P2-1 P1-0
我使用符号Pn-m 表示位置从m 到n 的位集的奇偶性。由于我们必须使用不相交的子集计算奇偶校验,因此我们只使用其中两个奇偶校验值中的一个,我将用? 标记其他奇偶校验值,以表示它们没有意义。所以我们有:
是:? P7-6? P5-4 ? P3-2 ? P1-0
y = y ^ (y >> 2)(考虑更多高阶位)
是:P15-14? P13-12 ? P11-10 ? P9-8 ? P7-6? P5-4 ? P3-2 ? P1-0
y>>2: P17-16 ? P15-14 ? P13-12 ? P11-10 ? P9-8 ? P7-6? P5-4 ? P3-2
y=: P17-14 ? P15-12 ? P13-10 ? P11-8 ? P9-6? P7-4 ? P5-2 ? P3-0
再次,由于我们只需要不相交子集的奇偶性,我们忽略结果的一些位以避免重叠集合,即P5-2、P9-6等,从而获得:
你:?? P15-12 ??? P11-8 ??? P7-4 ??? P3-0
y = y ^ (y >> 4)(考虑更多高阶位)
y: P23-20 ??? P19-16 ??? P15-12 ??? P11-8 ??? P7-4 ??? P3-0
y>>4: P27-24 ??? P23-20 ??? P19-16 ??? P15-12 ??? P11-8 ??? P7-4
y=: P27-20 ??? P23-16 ??? P19-12 ??? P15-8 ??? P11-4 ??? P7-0
再次,忽略重叠集(为了便于阅读,对 ?s 进行分组):
你:??? P23-16 ??? ??? P15-8 ??? ??? P7-0
y = y ^ (y >> 8)(考虑到所有 32 位):
是:P31-24 ??? ??? P23-16 ??? ??? P15-8 ??? ??? P7-0
y>>8: 0 000 0000 P31-24 ??? ??? P23-16 ??? ??? P15-8
y=: P31-24 ??? ??? P31-16 ??? ??? P23-8 ??? ??? P15-0
再次,忽略重叠集:
你:??? ??? P31-16 ??? ??? ??? ??? P15-0
y = y ^ (y >> 16)
你:??? ??? P31-16 ??? ??? ??? ??? P15-0
y>>16: 0000 0000 0 000 0000 ???? ??? P31-16
y=: ???? ??? P31-16 ??? ??? ??? ??? P31-0
return y & 1
你:??? ??? P31-16 ??? ??? ??? ??? P31-0
1:0000 0000 0 000 0000 0000 0000 1
y&1: 0000 0000 0 000 0000 0000 0000 P31-0
所以您可以看到返回的值只是参数x 的位的奇偶校验位P31-0,这正是我们想要的。