【问题标题】:What is the fastest way to check bits in variable using bitwise operations?使用按位运算检查变量中位的最快方法是什么?
【发布时间】:2019-12-07 08:52:56
【问题描述】:

例如,我有一个短(2 字节 = 16 位)变量:(在我的项目中,这是 00、01 和 10 的序列)

0001010101101001 = 0001.0101|0110.1001

我想检查这个变量是否包含位序列,例如我需要'01010101'(这是4 x 01)。

检查这个的最快方法是什么? 我找到了一些解决方案,但我确信存在更简单和更快的解决方案。

(pseudocode)
var =  0001010101101001;
need = 0000000001010101;
for(int i=0;i<4;i++)
{
     if(var&need==need)
           return 1;
     else
           var = var >> 2;
}

或:

(pseudocode)
var =   0001010101101001;
need1 = 0000000001010101;
need2 = 0000000101010100;
need3 = 0000010101010000;
need4 = 0001010101000000;
need5 = 0101010100000000;
if(var&need1==need1) return 1;
if(var&need2==need2) return 1;
if(var&need3==need3) return 1;
if(var&need4==need4) return 1;
if(var&need5==need5) return 1;
else return 0;

【问题讨论】:

  • 为什么不测试并找出答案?
  • 这两个例子是我的,但我想问是否有更简单和更快的解决方案
  • 你确定var &amp; 01010101 == 01010101,你不想var &amp; 11111111 == 01010101吗?
  • 是的,因为如果我的 var 是 XXXXXXXX01010101,那么 (var & 0000000001010101) = 0000000001010101
  • 在那种情况下无论如何都是一样的。如果var = 11111111,你想发生什么?现在的代码会返回 1,但应该返回 1 吗?

标签: bit-manipulation bitwise-operators bit bit-shift bitwise-and


【解决方案1】:

您的第一个解决方案很好:

for (int Count = 0; Count < 4; Count++)
{
    if ((Var & Need) == Need)
        Found = true;
    else
        Var = (UInt16)(Var >> 2);   
}

我实际上让事情变得复杂而不是简化。

这是使用掩码的替代解决方案。

using System;

public class Program
{
    public static void Main()
    {
        UInt16 Var = 0x1569;    //0001010101101001 0x1569
        UInt16 Need = 0x5A;     //0000000001011010 0x5A
                                //0000000001010101 0x55
                                //0000000001010110 0x56 
        UInt16[] Mask = { 0x00FF, 0x03FC, 0x0FF0, 0x3FC0, 0xFF00 };

        bool Found = false;
        for (int Count = 0; Count < 4; Count++)
            Found |= (((Var & Mask[Count]) ^ (Need << (Count + Count))) == 0);

        Console.WriteLine(Found);                
    }
}

【讨论】:

    【解决方案2】:

    还有一种方法:

    var &= 0101010101010101
    var &= var >> 2
    var &= var >> 4
    return var != 0
    

    奇数位无关紧要,因此只需在第一步中删除。

    然后,每 4 个相邻的“片段”(每个 2 位)分两步进行“与”运算,首先是每个片段直接在其左侧,然后通过在 2 个片段的距离内做同样的事情来复合。所以结果是一个 4 个“01”序列是否从那个位置开始的掩码。

    最后只需检查该掩码中是否设置了任何位。

    【讨论】:

      猜你喜欢
      • 2011-02-09
      • 2011-05-11
      • 2013-05-31
      • 2012-08-23
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-03
      相关资源
      最近更新 更多