none
How to convert part of a BitArray to byte[] array RRS feed

  • Question

  • Hello developers

    I have a BitArray and I need to take a part of it (from an index, with a length) and convert it to byte[] array, in the fastest way. 

    Thanks in advance

    Pablo

    Saturday, November 16, 2019 5:56 PM

Answers

  • So, in your bitarray, would positions 0 through 7 contain 00001111 respectively, or would they contain 11110000? That is, would the least significant bit, which in your example is the last 1, be in position 0 of the bitarray? This is "logical" in the sense that bit 0 of the byte is at position 0 of the bit array. But on the other hand it is "ilogical" in the sense that it would be the order that is opposite to the way in which we write it.

    Presuming that the bits are stored as least significant in the first position, then you can convert with a loop like this:

    public byte ConvertBitArrayToByte(BitArray ba, int startingPosition)
    {
        int result = 0;
        for (int i = startingPosition, n = 1; i < startingPosition + 8; i++, n <<= 1)
        {
            if (i >= ba.Length)
            {
                break;
            }
    
            if (ba[i])
            {
                result += n;
            }
        }
    
        return (byte)result;
    }
    

    This converts only one byte, but of course nothing stops you from calling it in a loop if you want to convert several.

    • Marked as answer by Tigre Pablito Friday, November 29, 2019 10:42 PM
    Sunday, November 17, 2019 10:28 PM
    Moderator
  • Hi Tigre Pablito,

    Thank you for posting here.

    For your question, you want to convert part of a BitArray to byte[] array.

    Until now, it seems that no way to meet your requirements.

    You can only get a part of the bitarray you want by iteration.

    And for your last question, I think the machine can recognize the difference between 11110000 and 00001111.

    This is a code example.

            static void Main(string[] args)
            {
                BitArray bit = new BitArray(new bool[]
                  {
                      true, true, true, true,
                      false, false, false, false,
                      false,false,false,false,
                      true,true,true,true
                  });
    
                byte[] bytes = ToByteArray(bit);
                foreach (var item in bytes)
                {
                    Console.WriteLine(item);
                }
    
                Console.WriteLine("Press any key to continue...");
                Console.ReadKey();
            }
            public static byte[] ToByteArray(BitArray bits)
            {
                int numBytes = bits.Count / 8;
                if (bits.Count % 8 != 0) numBytes++;
                
                byte[] bytes = new byte[numBytes];
                int byteIndex = 0, bitIndex = 0;
    
                for (int i = 0; i < bits.Count; i++)
                {
                    if (bits[i])
                        bytes[byteIndex] |= (byte)(1 << (7 - bitIndex));
    
                    bitIndex++;
                    if (bitIndex == 8)
                    {
                        bitIndex = 0;
                        byteIndex++;
                    }
                }
                return bytes;
            }
    

    Result:

    Hope this could be helpful.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Tigre Pablito Friday, November 29, 2019 10:42 PM
    Monday, November 18, 2019 7:22 AM

All replies

  • This needs some clarification. How do you want to make the conversion? Do you want the byte array to contain one byte with the value 0 or 1 for each bit in the BitArray? Or do you want to pack every 8 elements of the bitarray into one byte that contains a binary value made out of the 8 bits? in the latter case, do you want it to be little-endian or big-endian (i.e., first bit read from the bit array is the least significant bit or the byte, or the most significant bit)?

    Sunday, November 17, 2019 12:00 PM
    Moderator
  • Hi Alberto

    Thanks for replying

    I need to pack every 8 bools of the BitArray into a byte, and that to be in the format readable as a byte

    I´m not sure but I suppose 00001111 is 15 not 240

    Sunday, November 17, 2019 9:54 PM
  • So, in your bitarray, would positions 0 through 7 contain 00001111 respectively, or would they contain 11110000? That is, would the least significant bit, which in your example is the last 1, be in position 0 of the bitarray? This is "logical" in the sense that bit 0 of the byte is at position 0 of the bit array. But on the other hand it is "ilogical" in the sense that it would be the order that is opposite to the way in which we write it.

    Presuming that the bits are stored as least significant in the first position, then you can convert with a loop like this:

    public byte ConvertBitArrayToByte(BitArray ba, int startingPosition)
    {
        int result = 0;
        for (int i = startingPosition, n = 1; i < startingPosition + 8; i++, n <<= 1)
        {
            if (i >= ba.Length)
            {
                break;
            }
    
            if (ba[i])
            {
                result += n;
            }
        }
    
        return (byte)result;
    }
    

    This converts only one byte, but of course nothing stops you from calling it in a loop if you want to convert several.

    • Marked as answer by Tigre Pablito Friday, November 29, 2019 10:42 PM
    Sunday, November 17, 2019 10:28 PM
    Moderator
  • Isn't there something like a memcpy() or a way to convert, for example, 48 bools from the BitArray to a 6 bytes byte[] array, very fast? Or the method you gave me is the fastest and the only way is to iterate?

    About what bit is first, for me 00001111 is 15 and 11110000 is 240, and I suppose for the machine it is the same.

    Thank you!

    Sunday, November 17, 2019 11:04 PM
  • Using BitArray.CopyTo you can export the bits to an array of int, byte or bool. But you cannot export a part of bits.

    Monday, November 18, 2019 5:37 AM
  • Hi Tigre Pablito,

    Thank you for posting here.

    For your question, you want to convert part of a BitArray to byte[] array.

    Until now, it seems that no way to meet your requirements.

    You can only get a part of the bitarray you want by iteration.

    And for your last question, I think the machine can recognize the difference between 11110000 and 00001111.

    This is a code example.

            static void Main(string[] args)
            {
                BitArray bit = new BitArray(new bool[]
                  {
                      true, true, true, true,
                      false, false, false, false,
                      false,false,false,false,
                      true,true,true,true
                  });
    
                byte[] bytes = ToByteArray(bit);
                foreach (var item in bytes)
                {
                    Console.WriteLine(item);
                }
    
                Console.WriteLine("Press any key to continue...");
                Console.ReadKey();
            }
            public static byte[] ToByteArray(BitArray bits)
            {
                int numBytes = bits.Count / 8;
                if (bits.Count % 8 != 0) numBytes++;
                
                byte[] bytes = new byte[numBytes];
                int byteIndex = 0, bitIndex = 0;
    
                for (int i = 0; i < bits.Count; i++)
                {
                    if (bits[i])
                        bytes[byteIndex] |= (byte)(1 << (7 - bitIndex));
    
                    bitIndex++;
                    if (bitIndex == 8)
                    {
                        bitIndex = 0;
                        byteIndex++;
                    }
                }
                return bytes;
            }
    

    Result:

    Hope this could be helpful.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Tigre Pablito Friday, November 29, 2019 10:42 PM
    Monday, November 18, 2019 7:22 AM
  • Hello Timon

    When I wrote "and I suppose for the machine it is the same", I meant, that I supposed that the machine "thought" the same than me, that 00001111 is 15 and 11110000 is 240, NOT that the machine "thought" that 00001111 is equal to 11110000

    Thank you!

    Best Regards

    Pablo

    Friday, November 29, 2019 10:46 PM

  • When I wrote "and I suppose for the machine it is the same", I meant, that I supposed that the machine "thought" the same than me, that 00001111 is 15 and 11110000 is 240

    That would depend on the machine. Given the context of this forum it is most
    likely that you are using a PC with an Intel or compatible processor that has
    "little-endian" architecture. In that case your assumption that the computer
    recognizes bits in LSB 0 bit numbering order is almost certainly correct.

    However for some other hardware architectures - such as the PowerPC - which
    are "big-endian" devices the bit order may be reversed to use MSB 0 notation.
    With bits numbering from left to right the number 15 would be 11110000.

    See:

    Bit numbering
    https://en.wikipedia.org/wiki/LSB0

    - Wayne

    Saturday, November 30, 2019 7:27 AM