提取位标志的最有效方法

发布于 2024-08-31 22:16:48 字数 289 浏览 3 评论 0原文

我有这些可能的位标志。

1, 2, 4, 8, 16, 64, 128, 256, 512, 2048, 4096, 16384, 32768, 65536

所以每个数字就像服务器端的一个真/假陈述。因此,如果前 3 项,并且只有前 3 项在服务器端标记为“true”,则 Web 服务将返回 7。或者,如果上述所有 14 项均为 true,我仍然会从服务器端返回一个数字。 Web 服务是所有这些数字的总和。

处理我返回的号码以找出哪些项目被标记为“true”的最佳方法是什么?

I have these possible bit flags.

1, 2, 4, 8, 16, 64, 128, 256, 512, 2048, 4096, 16384, 32768, 65536

So each number is like a true/false statement on the server side. So if the first 3 items, and only the first 3 items are marked "true" on the server side, the web service will return a 7. Or if all 14 items above are true, I would still get a single number back from the web service which is is the sum of all those numbers.

What is the best way to handle the number I get back to find out which items are marked as "true"?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

顾铮苏瑾 2024-09-07 22:16:48

使用位掩码运算符。在 C 语言中:

 X & 8

如果设置了“8”位,则为 true。

您可以枚举位掩码,并计算设置了多少个。

如果确实是整个字包含位的情况,并且您只想简单地
计算设置了多少位,本质上您需要“人口计数”。绝对的
获得人口计数的最快方法通常是执行本机“popcnt”
在您机器的指令集中可用。

如果您不关心空间,您可以设置一个数组 countedbits[...],并通过预先计算的位计数按您的值进行索引。然后,一次内存访问即可计算您的位数。

经常使用的是简单的 "位旋转代码" 来计算位计数:

(Kernigan 的方法):(

unsigned int v; // count the number of bits set in v
unsigned int c; // c accumulates the total bits set in v
for (c = 0; v; c++)
{
  v &= v - 1; // clear the least significant bit set
}

并行位求和,32 位)

v = v - ((v >> 1) & 0x55555555);                    // reuse input as temporary
v = (v & 0x33333333) + ((v >> 2) & 0x33333333);     // temp
c = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // count

如果您以前没有见过位旋转黑客,那么您将会大饱眼福。

有趣的是,PHP 可能会用其中的一些算术来做一些有趣的事情。

Use a bit masking operator. In the C language:

 X & 8

is true, if the "8"s bit is set.

You can enumerate the bit masks, and count how many are set.

If it really is the case that the entire word contains bits, and you want to simply
compute how many bits are set, you want in essence a "population count". The absolute
fastest way to get a population count is to execute a native "popcnt" usually
available in your machine's instruction set.

If you don't care about space, you can set up a array countedbits[...] indexed by your value with precomputed bit counts. Then a single memory access computes your bit count.

Often used is just plain "bit twiddling code" that computes bit counts:

(Kernigan's method):

unsigned int v; // count the number of bits set in v
unsigned int c; // c accumulates the total bits set in v
for (c = 0; v; c++)
{
  v &= v - 1; // clear the least significant bit set
}

(parallel bit summming, 32 bits)

v = v - ((v >> 1) & 0x55555555);                    // reuse input as temporary
v = (v & 0x33333333) + ((v >> 2) & 0x33333333);     // temp
c = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // count

If you haven't seen the bit twiddling hacks before, you're in for a treat.

PHP, being funny, may do funny things with some of this arithmetic.

岁月苍老的讽刺 2024-09-07 22:16:48
if (7 & 1) { // if bit 1 is set in returned number (7)

}
if (7 & 1) { // if bit 1 is set in returned number (7)

}
哽咽笑 2024-09-07 22:16:48

认为这个问题很老可能对其他人有帮助。我将数字放入二进制中,因为这样更容易理解。该代码尚未经过测试,但希望逻辑清晰。该代码是 PHP 特定的。

define('FLAG_A', 0b10000000000000);  
define('FLAG_B', 0b01000000000000);
define('FLAG_C', 0b00100000000000);
define('FLAG_D', 0b00010000000000);
define('FLAG_E', 0b00001000000000);
define('FLAG_F', 0b00000100000000);
define('FLAG_G', 0b00000010000000);
define('FLAG_H', 0b00000001000000);
define('FLAG_I', 0b00000000100000);
define('FLAG_J', 0b00000000010000);
define('FLAG_K', 0b00000000001000);
define('FLAG_L', 0b00000000000100);
define('FLAG_M', 0b00000000000010);
define('FLAG_N', 0b00000000000001);

function isFlagSet($Flag,$Setting,$All=false){
  $setFlags = $Flag & $Setting;
  if($setFlags and !$All) // at least one of the flags passed is set
     return true;
  else if($All and ($setFlags == $Flag)) // to check that all flags are set
     return true;
  else
     return false;
}

用法:

if(isFlagSet(FLAG_A,someSettingsVariable)) // eg: someSettingsVariable = 0b01100000000010

if(isFlagSet(FLAG_A | FLAG_F | FLAG_L,someSettingsVariable)) // to check if atleast one flag is set

if(isFlagSet(FLAG_A | FLAG_J | FLAG_M | FLAG_D,someSettingsVariable, TRUE)) // to check if all flags are set

Thought the question is old might help someone else. I am putting the numbers in binary as its clearer to understand. The code had not been tested but hope the logic is clear. The code is PHP specific.

define('FLAG_A', 0b10000000000000);  
define('FLAG_B', 0b01000000000000);
define('FLAG_C', 0b00100000000000);
define('FLAG_D', 0b00010000000000);
define('FLAG_E', 0b00001000000000);
define('FLAG_F', 0b00000100000000);
define('FLAG_G', 0b00000010000000);
define('FLAG_H', 0b00000001000000);
define('FLAG_I', 0b00000000100000);
define('FLAG_J', 0b00000000010000);
define('FLAG_K', 0b00000000001000);
define('FLAG_L', 0b00000000000100);
define('FLAG_M', 0b00000000000010);
define('FLAG_N', 0b00000000000001);

function isFlagSet($Flag,$Setting,$All=false){
  $setFlags = $Flag & $Setting;
  if($setFlags and !$All) // at least one of the flags passed is set
     return true;
  else if($All and ($setFlags == $Flag)) // to check that all flags are set
     return true;
  else
     return false;
}

Usage:

if(isFlagSet(FLAG_A,someSettingsVariable)) // eg: someSettingsVariable = 0b01100000000010

if(isFlagSet(FLAG_A | FLAG_F | FLAG_L,someSettingsVariable)) // to check if atleast one flag is set

if(isFlagSet(FLAG_A | FLAG_J | FLAG_M | FLAG_D,someSettingsVariable, TRUE)) // to check if all flags are set
戈亓 2024-09-07 22:16:48

一种方法是循环遍历您的数字,将其左移(即除以 2)并使用 & 将第一位与 1 进行比较。操作数。

One way would be to loop through your number, left-shifting it (ie divide by 2) and compare the first bit with 1 using the & operand.

独自唱情﹋歌 2024-09-07 22:16:48

由于 php 代码没有明确的答案,我添加了这个工作示例:

// returns array of numbers, so for 7 returns array(1,2,4), etc..

function get_bits($decimal) {
  $scan = 1;
  $result = array();
  while ($decimal >= $scan){
    if ($decimal & $scan) $result[] = $scan;
    $scan<<=1; 
  }
  return $result;
}

As there is no definite answer with php code, I add this working example:

// returns array of numbers, so for 7 returns array(1,2,4), etc..

function get_bits($decimal) {
  $scan = 1;
  $result = array();
  while ($decimal >= $scan){
    if ($decimal & $scan) $result[] = $scan;
    $scan<<=1; 
  }
  return $result;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文