jmasterx
jmasterx

Reputation: 54113

Convert Bitfield to array

I have a uint called Forced that contains 32 bits.

I do stuff like:

if(Forced & 512)
   doStuff();

What I am looking to do is put forced into an array which would then turn into:

if(ForcedArray[(int)Math.Log(512,2)])
   doStuff();

Is there a convenient way in .NET to do this? What would be a convenient way to convert a bitfield to an array?

Upvotes: 4

Views: 357

Answers (3)

Riad Baghbanli
Riad Baghbanli

Reputation: 3319

public static class UIntExtensions
{
    public static byte[] GetBitArray(this uint v)
    {
        var r = byte[32];
        for (var i = 0; i < 32; ++i)
        {
            r[i] = v & 1;
            v = v >> 1
        }
        return r;
    }
}

Upvotes: 0

Alexei Levenkov
Alexei Levenkov

Reputation: 100527

Using bit-shift to access bits of an integer Forced & (1 << bitNumber) sounds like a good approach (nice function wrapping the access is shown in Ron Beyer's answer).

Most reader of the code will be puzzled by such transformation of compact single-word field into complicated data structure like array. Please consider avoiding that unless there are some other reasons (external API constraint like JSON serialization) or significant readability gain.

As intermediate approach you can create small wrapper structure that holds integer value and additionally exposes indexed access to each bit (preferably immutable).

If you really want and array - basic for loop or LINQ can be used to transform each bit into boolean. I.e. If it is just one integer (may need to adjust order depending which bit you need first, this one puts lowest bit first):

var array = Enumerable.Range(0, 32)
  .Select(bitNumber => (Forced & (1 << bitNumber)) !=0)
  .ToArray();

Upvotes: 3

Ron Beyer
Ron Beyer

Reputation: 11273

You could write an extension method for this:

public static class UIntExtensions
{
    public static bool IsBitSet(this uint i, int bitNumber)
    {
        return i & (1 << bitNumber) != 0;
    }
}

Or, if you want to do this the C#6 way:

public static class UIntExtensions
{
    public static bool IsBitSet(this uint i, int bitNumber) => (i & (1 << bitNumber)) != 0;
}

Which is pretty easy to use from code:

if(Forced.IsBitSet((int)Math.Log(512,2)))
   doStuff();

Obviously, a few checks for having a bit number >= 0 or <= 31 need to be added, but you get the idea.

Upvotes: 4

Related Questions