让我们尝试一下直觉countmore
。
首先,~0UL/255*(127-n)
是一种将值127-n
并行复制到字中所有字节的巧妙方法。为什么它有效? ~0
所有字节为 255。因此,~0/255
是1
所有字节。乘以(127-n)
一开始提到的“复制”。
该术语只是上述零~0UL/255*127
的特例。n
它将 127 复制到所有字节中。那就是0x7f7f7f7f
如果单词是4个字节。“Anding”x
将每个字节中的高位清零。
这是第一个学期(x)&~0UL/255*127)
。x
结果与除了每个字节中的高位清零之外的结果相同。
第二项~0UL/255*(127-(n))
如上:127-n
复制到每个字节。
对于任何给定的字节x[i]
,将这两项相加就可以得到127-n+x[i]
if x[i]<=127
。该数量将在任何时候设置高位x[i]>n
。最容易将其视为添加两个 7 位无符号数。结果“溢出”到第 8 位,因为结果为 128 或更多。
所以看起来该算法将使用每个字节的第 8 位作为布尔值指示x[i]>n
。
那么另一种情况x[i]>127
呢?在这里我们知道字节多是n
因为算法规定的n<=127
。第 8 位应该始终为 1。令人高兴的是,和的第 8 位无关紧要,因为下一步“或”的结果是x
。由于x[i]
第 8 位设置为 1 当且仅当它为 128 或更大时,此操作仅在总和可能提供错误值时“强制”第 8 位为 1。
总结到目前为止,“或”结果在其第 i 个字节中的第 8 位设置为 1 当且仅当x[i]>n
。好的。
下一个操作&~0UL/255*128
将所有内容设置为零,除了所有那些感兴趣的第 8 位。这是与 0x80808080 的“与”...
现在的任务是找到设置为 1 的这些位的数量。为此,countmore
使用一些基本的数论。首先它右移 7 位,所以感兴趣的位是 b0、b8、b16... 这个字的值是
b0 + b8*2^8 + b16*2^16 + ...
一个美丽的事实是 1 == 2^8 == 2^16 == ... mod 255。换句话说,每个 1 位是 1 mod 255。因此找到移位结果的 mod 255 与求和 b0+b8+b16+...
哎呀。我们完成了。