Get a specific bit from byte

C#

C# Problem Overview


I have a byte, specifically one byte from a byte array which came in via UDP sent from another device. This byte stores the on/off state of 8 relays in the device.

How do I get the value of a specific bit in said byte? Ideally an extension method would look the most elegant and returning a bool would make the most sense to me.

public static bool GetBit(this byte b, int bitNumber)
{
    //black magic goes here
}

C# Solutions


Solution 1 - C#

Easy. Use a bitwise AND to compare your number with the value 2^bitNumber, which can be cheaply calculated by bit-shifting.

//your black magic
var bit = (b & (1 << bitNumber-1)) != 0;

EDIT: To add a little more detail because there are a lot of similar answers with no explanation:

A bitwise AND compares each number, bit-by-bit, using an AND join to produce a number that is the combination of bits where both the first bit and second bit in that place were set. Here's the logic matrix of AND logic in a "nibble" that shows the operation of a bitwise AND:

  0101
& 0011
  ----
  0001 //Only the last bit is set, because only the last bit of both summands were set

In your case, we compare the number you passed with a number that has only the bit you want to look for set. Let's say you're looking for the fourth bit:

  11010010
& 00001000
  --------
  00000000 //== 0, so the bit is not set

  11011010
& 00001000
  --------
  00001000 //!= 0, so the bit is set

Bit-shifting, to produce the number we want to compare against, is exactly what it sounds like: take the number, represented as a set of bits, and shift those bits left or right by a certain number of places. Because these are binary numbers and so each bit is one greater power-of-two than the one to its right, bit-shifting to the left is equivalent to doubling the number once for each place that is shifted, equivalent to multiplying the number by 2^x. In your example, looking for the fourth bit, we perform:

       1 (2^0) << (4-1) ==        8 (2^3)
00000001       << (4-1) == 00001000

Now you know how it's done, what's going on at the low level, and why it works.

Solution 2 - C#

While it's good to read and understand Josh's answer, you'll probably be happier using the class Microsoft provided for this purpose: System.Collections.BitArray It's available in all versions of .NET Framework.

Solution 3 - C#

This

public static bool GetBit(this byte b, int bitNumber) {
   return (b & (1 << bitNumber)) != 0;
}

should do it, I think.

Solution 4 - C#

This is works faster than 0.1 milliseconds.

return (b >> bitNumber) & 1;

Solution 5 - C#

another way of doing it :)

return ((b >> bitNumber) & 1) != 0;

Solution 6 - C#

Using BitArray class and making an extension method as OP suggests:

public static bool GetBit(this byte b, int bitNumber)
{
	System.Collections.BitArray ba = new BitArray(new byte[]{b});
	return ba.Get(bitNumber);
}

Solution 7 - C#

try this:

return (b & (1 << bitNumber))>0;

Solution 8 - C#

The method is to use another byte along with a bitwise AND to mask out the target bit.

I used convention from my classes here where "0" is the most significant bit and "7" is the least.

public static class ByteExtensions
{
    // Assume 0 is the MSB andd 7 is the LSB.
    public static bool GetBit(this byte byt, int index)
    {
        if (index < 0 || index > 7)
            throw new ArgumentOutOfRangeException();

        int shift = 7 - index;

        // Get a single bit in the proper position.
        byte bitMask = (byte)(1 << shift);

        // Mask out the appropriate bit.
        byte masked = (byte)(byt & bitMask);

        // If masked != 0, then the masked out bit is 1.
        // Otherwise, masked will be 0.
        return masked != 0;
    }
}

Solution 9 - C#

Try the code below. The difference with other posts is that you can set/get multiple bits using a mask (field). The mask for the 4th bit can be 1<<3, or 0x10, for example.

    public int SetBits(this int target, int field, bool value)
    {
        if (value) //set value
        {
            return target | field;
        }
        else //clear value
        {
            return target & (~field);
        }
    }

    public bool GetBits(this int target, int field)
    {
        return (target & field) > 0;
    }

** Example **

        bool is_ok = 0x01AF.GetBits(0x10); //false
        int res = 0x01AF.SetBits(0x10, true);
        is_ok = res.GetBits(0x10);  // true

Solution 10 - C#

[Flags]
enum Relays : byte
{
    relay0 = 1 << 0,
    relay1 = 1 << 1,
    relay2 = 1 << 2,
    relay3 = 1 << 3,
    relay4 = 1 << 4,
    relay5 = 1 << 5,
    relay6 = 1 << 6,
    relay7 = 1 << 7
}

public static bool GetRelay(byte b, Relays relay)
{
    return (Relays)b.HasFlag(relay);
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionkeithwarren7View Question on Stackoverflow
Solution 1 - C#KeithSView Answer on Stackoverflow
Solution 2 - C#Ben VoigtView Answer on Stackoverflow
Solution 3 - C#user197015View Answer on Stackoverflow
Solution 4 - C#asimolmezView Answer on Stackoverflow
Solution 5 - C#pierrozView Answer on Stackoverflow
Solution 6 - C#Jay WalkerView Answer on Stackoverflow
Solution 7 - C#AliostadView Answer on Stackoverflow
Solution 8 - C#SapphView Answer on Stackoverflow
Solution 9 - C#John AlexiouView Answer on Stackoverflow
Solution 10 - C#jabukufoView Answer on Stackoverflow