4

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?

jmasterx
  • 52,639
  • 96
  • 311
  • 557

3 Answers3

4

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.

Ron Beyer
  • 11,003
  • 1
  • 19
  • 37
3

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();
Community
  • 1
  • 1
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • The legitimate purposes for bit arrays are often to micro-optimize performance and/or memory usage. Not sure that I would suggest a Linq answer, as it will likely void any gains from micro-optimization. Then again, bit arrays are probably used in many contexts where that optimization is not necessary... – Eric J. Dec 14 '15 at 20:22
  • 1
    @EricJ. I seriously doubt that OP is looking for micro-optimizations - `(int)Math.Log(512,2)` does not look like anything one would use in performance sensitive code. Probably some other reason - maybe using array makes particular code more readable? (Again one could just wrap integer into struct with indexer if performance/size matter) – Alexei Levenkov Dec 14 '15 at 20:28
  • Maybe not the OP, but I just read http://stackoverflow.com/q/21877966/141172 and it reminded me that people have a habit of copying and using code they don't fully understand. For that reason, I prefer the answer given by Ron, or indeed your comment under the question. – Eric J. Dec 14 '15 at 20:44
  • 1
    @EricJ. :) it even get weirder - people copy paste code, than give to someone else to copy and that third person has to come back to SO to ask for explanations like happened [in this question](http://stackoverflow.com/a/34275738/477420) – Alexei Levenkov Dec 14 '15 at 20:51
0
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;
    }
}
Riad Baghbanli
  • 3,105
  • 1
  • 12
  • 20
  • Could you explain your code a bit? In particular, how would you say this answers the question "*What would be a convenient way to convert a bitfield to an array?*"? You should know your answer is in a [queue for deletion](http://stackoverflow.com/review/low-quality-posts/10561061). – Wai Ha Lee Dec 14 '15 at 22:47