繁体   English   中英

位操作:检测字节中是否设置了至少5位?

[英]Bit manipulation: detect if at least 5 bits in byte are set?

检查二进制数中是否设置了最小位数的最佳方法是什么?

例如,我需要查看此序列中是否至少将5位设置为1:

101100010

我一直在寻找使用位掩码之类的东西,但是对于如何做到这一点更加困惑。

任何帮助赞赏。

来自http://blog.faultylabs.com/2011.php?p=jsbitfun

/*
 popCnt(n)
 Returns the bit population count of n (that is: how many bits in n are set to 1)
 n must be an unsigned integer in the range [0..(2^32)-1]
 This lookup-table-free method is from Kernighan & Ritchie's "The C Programming Language"
 Exercise 2.9 (on page 62 of my copy). Not sure whether they (K&R) are the inventors.
*/
function popCnt(n) {
    n >>>= 0 /* force uint32 */
    for(var popcnt = 0; n; n &= n - 1) {
        popcnt++
    }
    return popcnt
}

有关其他算法的详细信息,请参见http://en.wikipedia.org/wiki/Hamming_weight

如果您正在尝试学习使用位,请使用位掩码。

如果您需要一个非常简单的解决方案,只需将整数转换为其二进制值的字符串表示形式,并计算1的计数:

var i = 0x1 +0x4 + 0x8 +0x80; // 10001101 in binary
var numberOf1s = i.toString(2).split('1').length-1; // 4

总而言之,您只需要一行代码即可:

if(<insert your var>.toString(2).split('1').length-1 >=5) {
  //At least 5 bits are set
}

首先使用位掩码,尤其是在尝试学习时。 将其视为一系列位时,这是最逻辑上最简单的方法。 (现在有很多可以做聪明的把戏,但首先是第一和,与发动机无数像JS语言,实现可能使聪明,不那么聪明。)

为了测试是否设置了位b ,当input & (1 << b)非0时,它被设置,当然1 << b00000001 (0x01), 00000010 (0x02), 00000100 (0x04), 00001000 (0x08) )当b为0,1,2,3等等时,等等。 (注1是00000001以及<<如何将模式左移 b位)。

因此,对于每个0 <= b <8,查看该位是否已设置。 如果是,请将一个添加到计数器。

现在我们知道第一个八位字节中设置了多少位。

还要注意,我们关心的b只有一小组有限的值。 因此,我们可以消除循环并知道每个循环迭代的每个1 << b (像Firefox这样的浏览器在单个表达式时可以非常快速地处理一系列逐位数学运算。)

快乐的编码


为了好玩,我决定创建一个popCnt (和strCount )的快速性能测试用例,如其他答案所示,以及一个专门的位计数器fastCount8 ,它只使用数学运算而不会过于聪明。 simpleCount8如上所述。

假设fastCount8 (和simpleCount8 )都限制为单个八位字节(第一个字节),但对于这种特殊情况, fastCount8某些浏览器中速度要快得多。 (它在FF8中明显更快,但在IE9中仅popCnt快一些,在Chrome 16中速度更慢 。)正如预期的那样, strCountpopCnt慢得多,而simpleCount8则不popCnt

这是jsperf测试fastCount8

function fastCount8(n) {
    // >> has higher precedence than &
    return (n >> 0 & 1)
      + (n >> 1 & 1)
      + (n >> 2 & 1)
      + (n >> 3 & 1)
      + (n >> 4 & 1)
      + (n >> 5 & 1)
      + (n >> 6 & 1)
      + (n >> 7 & 1)
}

更新了lookup8lookupN (和一些变体), fastCount8NfastCount8N2 结果非常壮观:FF8做了一些绝对惊人的数学优化,其他浏览器(我测试过)甚至无法接近保持给定的表达式。 此外,其他结果可能有点令人惊讶,并展示不同浏览器如何优化不同的东西......

...总而言之, lookup8lookupN2b在浏览器中看起来最一致......至少在给定的n范围内。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM