Reputation: 4199
How to check if a certain bit in a byte is set?
bool IsBitSet(Byte b,byte nPos)
{
return .....;
}
Upvotes: 77
Views: 134516
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
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
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
Reputation: 8363
C#6 single-line:
bool IsBitSet(byte b, int pos) => (b >> pos & 1) == 1;
Upvotes: 0
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
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
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
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
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
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
Reputation: 839114
Right shift your input n bits down and mask with 1, then test whether you have 0 or 1.
Upvotes: 6
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