How to check if a certain bit in a byte is set?
bool IsBitSet(Byte b,byte nPos)
{
return .....;
}
How to check if a certain bit in a byte is set?
bool IsBitSet(Byte b,byte nPos)
{
return .....;
}
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.
Equivalent to Mario F code, but shifting the byte instead of mask:
bool IsBitSet(byte b, int pos)
{
return ((b >> pos) & 1) != 0;
}
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. :)
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
.
Right shift your input n bits down and mask with 1, then test whether you have 0 or 1.
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];
}
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));
}
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;
meetingDays.HasFlag(Days.Wednesday)
instead. Enum.HasFlag Reference –
Mannerless 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);
}
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
Math.Pow()
returns a double. You should avoid that when you work with bits / flags. If you use any kind of floats instead of ints you may be facing rounding errors and quantization effects. Instead use left-shifting of 1 by n bits (1 << n
) as shown in other answers. This is mathematically identical to creating powers of 2 (2^n == 1<<n
) and does not create any quantization deviations because it is all done on integers. –
Transcription C#6 single-line:
bool IsBitSet(byte b, int pos) => (b >> pos & 1) == 1;
© 2022 - 2024 — McMap. All rights reserved.