Manjoor
Manjoor

Reputation: 4199

Checking if a bit is set or not

How to check if a certain bit in a byte is set?

bool IsBitSet(Byte b,byte nPos)
{
   return .....;
}

Upvotes: 77

Views: 134516

Answers (13)

CaseyHofland
CaseyHofland

Reputation: 538

To Jim Lahman's answer, there's an optimization you can do:

public void DoStuff(int mask)
{
    for (int i = 0; mask > 0; mask >>= 1)
    {
        if ((mask & 1) != 0)
        {
            array[i].DoSomeOtherStuff();
        }
        i++;
    }
}

This ensures that if your mask is 0000_0101 it will only iterate 3 times until it discovers there's no more bits to be found.

This doesn't allow negatives either, which in my case is what I want.

Upvotes: 0

Sk1
Sk1

Reputation: 11

Use Enum with [System.Flags] property and byte, it will treat Enum as set of bits. Later use bitwise operator AND, and compare it against needed value. Here we check if 6th bit value is 1.

[Flags]
public enum Days : byte
{
    None      = 0b_0000_0000,  // 0
    Monday    = 0b_0000_0001,  // 1
    Tuesday   = 0b_0000_0010,  // 2
    Wednesday = 0b_0000_0100,  // 4
    Thursday  = 0b_0000_1000,  // 8
    Friday    = 0b_0001_0000,  // 16
    Saturday  = 0b_0010_0000,  // 32
    Sunday    = 0b_0100_0000,  // 64
}
Days meetingDays = Days.Monday | Days.Tuesday  | Days.Wednesday ; 
bool isMeetingOnWednesday = (meetingDays & Days.Wednesday) == Days.Wednesday;

Upvotes: 1

Chris Bruce
Chris Bruce

Reputation: 11

If you want to check multiple bits for any byte length (byte, int, long, etc.) in one shot vs shifting and looping, you can try the extension method below on your bit numeric type of choice (ByteExtension, IntExtension, LongExtension, etc.)

   public static class ByteExtensions
   {
      /// <summary>
      /// Return true if the respective set bits in mask are set in b.  Otherwise return false.
      /// </summary>
      /// <param name="b">byte to evaluate</param>
      /// <param name="mask">byte where if a bit is 1, test that b is also a 1</param>
      /// <returns>Return true if the respective set bits in mask are set in b.  Otherwise return false.</returns>
      public static bool AreBitsSet(this byte b, byte mask) => (b & mask) == mask;
      /// <summary>
      /// Return true if the respective set bits in value are cleared in b.  Otherwise return false.
      /// </summary>
      /// <param name="b">byte to evaluate</param>
      /// <param name="value">byte where if a bit is 1, test that b is also a 1</param>
      /// <returns>True if the respective set bits in value are cleared in b.  Otherwise return false.</returns>
      public static bool AreBitsCleared(this byte b, byte value) => (~b & value) == value;
    }

How to use:

      [TestMethod()]
      public void TestBits()
      {
         // Data
         byte b1 = 0b10010001;
         byte b2 = 0b11010001;
         byte b3 = 0b11010011;
         byte b4 = 0b00010001;

         // In a set mask, 1 means test for 1 in data byte
         byte setMask = 0b10010001;
         Debug.Assert(b1.AreBitsSet(setMask));
         Debug.Assert(b2.AreBitsSet(setMask));
         Debug.Assert(b3.AreBitsSet(setMask));
         Debug.Assert(!b4.AreBitsSet(setMask));

         // In a cleared mask, a 1 means test for 0 in data byte
         byte clearedMask = 0b01101100;
         Debug.Assert(b1.AreBitsCleared(clearedMask));
         Debug.Assert(!b2.AreBitsCleared(clearedMask));
         Debug.Assert(!b2.AreBitsCleared(clearedMask));
         Debug.Assert(b4.AreBitsCleared(clearedMask));
      }

Upvotes: 1

Arvis
Arvis

Reputation: 8363

C#6 single-line:

bool IsBitSet(byte b, int pos) => (b >> pos & 1) == 1;

Upvotes: 0

Rafael Telles
Rafael Telles

Reputation: 151

x == (x | Math.Pow(2, y));

int x = 5;

x == (x | Math.Pow(2, 0)) //Bit 0 is ON
x == (x | Math.Pow(2, 1)) //Bit 1 is OFF
x == (x | Math.Pow(2, 2)) //Bit 2 is ON

Upvotes: 0

Shimmy Weitzhandler
Shimmy Weitzhandler

Reputation: 104821

Based on Mario Fernandez's answer, I thought why not have it in my toolbox as a handy extension method not limited to datatype, so I hope it's OK to share it here:

/// <summary>
/// Returns whether the bit at the specified position is set.
/// </summary>
/// <typeparam name="T">Any integer type.</typeparam>
/// <param name="t">The value to check.</param>
/// <param name="pos">
/// The position of the bit to check, 0 refers to the least significant bit.
/// </param>
/// <returns>true if the specified bit is on, otherwise false.</returns>
public static bool IsBitSet<T>(this T t, int pos) where T : struct, IConvertible
{
 var value = t.ToInt64(CultureInfo.CurrentCulture);
 return (value & (1 << pos)) != 0;
}

Note: Do not use for performance critical operations, as this method always converts to long.

Upvotes: 11

kaalus
kaalus

Reputation: 4574

Equivalent to Mario F code, but shifting the byte instead of mask:

bool IsBitSet(byte b, int pos)
{
   return ((b >> pos) & 1) != 0;
}

Upvotes: 12

Jim Lahman
Jim Lahman

Reputation: 2767

To check the bits in a 16-bit word:

  Int16 WordVal = 16;
  for (int i = 0; i < 15; i++)
  {
     bitVal = (short) ((WordVal >> i) & 0x1);
     sL = String.Format("Bit #{0:d} = {1:d}", i, bitVal);
     Console.WriteLine(sL);
  }

Upvotes: 0

RedPaladin
RedPaladin

Reputation: 784

something like

return ((0x1 << nPos) & b) != 0

Upvotes: 2

Brian Chavez
Brian Chavez

Reputation: 8593

This also works (tested in .NET 4):

void Main()
{
    //0x05 = 101b
    Console.WriteLine(IsBitSet(0x05, 0)); //True
    Console.WriteLine(IsBitSet(0x05, 1)); //False
    Console.WriteLine(IsBitSet(0x05, 2)); //True
}

bool IsBitSet(byte b, byte nPos){
    return new BitArray(new[]{b})[nPos];
}

Upvotes: 5

Aamir
Aamir

Reputation: 15576

Here is the solution in words.

Left shift an integer with initial value 1 n times and then do an AND with the original byte. If the result is non-zero, bit is Set otherwise not. :)

Upvotes: 11

Mark Byers
Mark Byers

Reputation: 839114

Right shift your input n bits down and mask with 1, then test whether you have 0 or 1.

Upvotes: 6

Mario F
Mario F

Reputation: 47287

sounds a bit like homework, but:

bool IsBitSet(byte b, int pos)
{
   return (b & (1 << pos)) != 0;
}

pos 0 is least significant bit, pos 7 is most.

Upvotes: 210

Related Questions