简体   繁体   English

如何计算从左到右直到第一个0的字节中顺序设置的位数?

[英]How can I count amount of sequentially set bits in a byte from left to right until the first 0?

I'm not good in English, I can't ask it better, but please below: 我的英语不好,我不能更好地询问,但是请在下面:

if byte in binary is 1 0 0 0 0 0 0 0 then result is 1 如果二进制字节为1 0 0 0 0 0 0 0,则结​​果为1
if byte in binary is 1 1 0 0 0 0 0 0 then result is 2 如果二进制字节为1 1 0 0 0 0 0 0,则结​​果为2
if byte in binary is 1 1 1 0 0 0 0 0 then result is 3 如果二进制字节为1 1 1 0 0 0 0 0,则结​​果为3
if byte in binary is 1 1 1 1 0 0 0 0 then result is 4 如果二进制字节为1 1 1 1 0 0 0 0,则结​​果为4
if byte in binary is 1 1 1 1 1 0 0 0 then result is 5 如果二进制字节为1 1 1 1 1 0 0 0,则结​​果为5
if byte in binary is 1 1 1 1 1 1 0 0 then result is 6 如果二进制字节为1 1 1 1 1 1 0 0,则结​​果为6
if byte in binary is 1 1 1 1 1 1 1 0 then result is 7 如果二进制字节为1 1 1 1 1 1 1 0,则结​​果为7
if byte in binary is 1 1 1 1 1 1 1 1 then result is 8 如果二进制字节为1 1 1 1 1 1 1 1,则结果为8

But if for example the byte in binary is 1 1 1 0 * * * * then result is 3. 但是,例如,如果二进制字节为1 1 1 0 * * * *,则结果为3。

I would determine how many bit is set contiguous from left to right with one operation. 我将确定一次操作从左到右设置多少位连续。

The results are not necessary numbers from 1-8, just something to distinguish. 结果不是1-8的必要数字,只是可以区分的数字。 I think it's possible in one or two operations, but I don't know how. 我认为可以在一两个操作中实现,但我不知道如何操作。

If you don't know a solution as short as 2 operations, please write that too, and I won't try it anymore. 如果您不知道短于2个操作的解决方案,也请写下来,我将不再尝试。

Easiest non-branching solution I can think of: 我能想到的最简单的非分支解决方案:

y=~x
y|=y>>4
y|=y>>2
y|=y>>1

Invert x, and extend the lefttmost 1-bit (which corresponds to the leftmost 0-bit in the non-inverted value) to the right. 反转x,并向右扩展最左边的1位(对应于非取反值中最左边的0位)。 Will give distinct values (not 1-8 though, but it's pretty easy to do a mapping). 会给出不同的值(虽然不是1-8,但是映射很容易)。

110* ****

turns into 变成

001* ****
001* **1*
001* 1*1*
0011 1111

EDIT : 编辑

As pointed out in a different answer, using a precomputed lookup table is probably the fastets. 正如在另一个答案中指出的那样,使用预计算的查找表可能是最快捷的方法。 Given only 8 bits, it's probably even feasible in terms of memory consumption. 仅给出8位,就内存消耗而言,这甚至可能是可行的。

EDIT : 编辑

Heh, woops, my bad.. You can skip the invert, and do ands instead. 嘿,糟糕,我的坏事。您可以跳过倒置,然后执行与号。

x&=x>>4
x&=x>>2
x&=x>>1

here 这里

110* ****

gives

110* **0*
110* 0*0*
1100 0000

As you can see all values beginning with 110 will result in the same output (1100 0000). 如您所见,所有以110开头的值都将产生相同的输出(1100 0000)。

EDIT: 编辑:

Actually, the 'and' version is based on undefined behavior (shifting negative numbers), and will usually do the right thing if using signed 8-bit (ie char, rather than unsigned char in C), but as I said the behavaior is undefined and might not always work. 实际上,“ and”版本基于未定义的行为(移动负数),如果使用带符号的8位(即char,而不是C中的无符号char),通常会做正确的事,但是正如我所说的,未定义,可能并不总是有效。

I'd second a lookup table... otherwise you can also do something like: 我将第二个查询表...否则,您也可以执行以下操作:

unsigned long inverse_bitscan_reverse(unsigned long value)
{
    unsigned long bsr = 0;
    _BitScanReverse(&bsr, ~value); // x86 bsr instruction
    return bsr;
}

EDIT: Not that you have to be careful of the special case where "value" has no zeroed bits. 编辑:不是您必须注意“值”没有归零位的特殊情况。 See the documentation for _BitScanReverse. 请参见_BitScanReverse的文档。

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

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