What is wrong with BitArray.CopyTo()? (I might have posted this twice, sorry)

  • Thread starter Thread starter SpookyET
  • Start date Start date
S

SpookyET

For some reason the method reverses the array, which is very annoying. If
I put in 00001000 which is 8, i get back 00010000 which is 16. If I put in
00000100 (4), I get back 00100000 (32). This means that CopyTo is
useless, since I have to reverse it to get it right.

public static void Main()
{
bool[] bools = new bool[8] { false, false, false, false, false, true,
false, false};
BitArray bits = new BitArray(bools);
byte myByte = 0;
byte[] myByteArray = new byte[bits.Count / 8];
int index;

for (index = 0; index < bits.Length; index++)
{
myByte <<= 1;
myByte |= Convert.ToByte(bits[index]);
}

// An uglier way.
// for (index = 0; index < bits.Length; index++)
// {
// myByte = ((byte)((myByte << 1) | (bits[index] ? 1 : 0)));
// }

bits.CopyTo(myByteArray, 0);
Console.WriteLine(myByte);
Console.WriteLine(myByteArray[0]);
Console.ReadLine();
}

Wouldn't it be better if there was a struct System.Bit with a C# alias of
"bit", that accepts 0/1 and true/false.
bit myBit = 1;
byte myByte = 0;

myByte <<= 1;
byte |= myBit;

This is much easier and cleaner, and no casting. I know about enum with
the [FlagsAttribute], but this has nothing to do with flags/options, for
those of you that might suggest that.
 
Hi
The BitArray has following content "00100000" While Creating a Bitarray the first element in the bools array is the LSB for BitArray and last element is the MSB for BitArray hence if true come is in 5th position you will get 2^5 is 32. The for loop were you caluclate the value is also misleading since the first element is LSB you should shift a number with respect to the index. Hence MSB in the last index will get shifted to last postion

Pradeep Kumar K

----- SpookyET wrote: ----

For some reason the method reverses the array, which is very annoying. I
I put in 00001000 which is 8, i get back 00010000 which is 16. If I put i
00000100 (4), I get back 00100000 (32). This means that CopyTo i
useless, since I have to reverse it to get it right

public static void Main(

bool[] bools = new bool[8] { false, false, false, false, false, true
false, false}
BitArray bits = new BitArray(bools)
byte myByte = 0
byte[] myByteArray = new byte[bits.Count / 8]
int index

for (index = 0; index < bits.Length; index++

myByte <<= 1
myByte |= Convert.ToByte(bits[index])


// An uglier way
// for (index = 0; index < bits.Length; index++
//
// myByte = ((byte)((myByte << 1) | (bits[index] ? 1 : 0)))
//

bits.CopyTo(myByteArray, 0)
Console.WriteLine(myByte)
Console.WriteLine(myByteArray[0])
Console.ReadLine()


Wouldn't it be better if there was a struct System.Bit with a C# alias o
"bit", that accepts 0/1 and true/false
bit myBit = 1
byte myByte = 0

myByte <<= 1
byte |= myBit

This is much easier and cleaner, and no casting. I know about enum wit
the [FlagsAttribute], but this has nothing to do with flags/options, fo
those of you that might suggest that
 
SpookyET said:
For some reason the method reverses the array, which is very annoying.

Hmm... I can't reproduce that with a bool array. Here's a test program
which shows it working okay:

using System;
using System.Collections;

public class Test
{
static void Main()
{
bool[] foo = {false, false, false, false,
true, false, false, false};
Show(foo);
BitArray x = new BitArray(foo);
// Show that it really is doing the copy
Array.Clear(foo, 0, foo.Length);
Show(foo);
x.CopyTo(foo, 0);
Show(foo);
}

static void Show(bool[] values)
{
foreach(bool b in values)
{
Console.Write(b ? '1' : '0');
}
Console.WriteLine();
}
}

No reversal there.

Now, in your case you're using a byte array, not a bool array. You seem
to be assuming that the array you pass into BitArray is treated with
the right-most bool as bit 0, but it's not - it's bit 7. The order of
the bits is the order of the array, which makes sense if you think
about it normally, it's just not the way we usually look at bits in a
byte (which is fine, as this is a sequence of bits, it's not a byte).
Indeed if you pass in a byte array to the constructor, the order is
preserved.

I believe BitArray.ToArray is doing exactly what it should be doing,
you're just slightly confused as to what the BitArray(bool[])
constructor does.
 
CopyTo treats arrays of different types differently, look at the code with
a decompiler. Try my code and see for yourself.

SpookyET said:
For some reason the method reverses the array, which is very annoying.

Hmm... I can't reproduce that with a bool array. Here's a test program
which shows it working okay:

using System;
using System.Collections;

public class Test
{
static void Main()
{
bool[] foo = {false, false, false, false,
true, false, false, false};
Show(foo);
BitArray x = new BitArray(foo);
// Show that it really is doing the copy
Array.Clear(foo, 0, foo.Length);
Show(foo);
x.CopyTo(foo, 0);
Show(foo);
}
static void Show(bool[] values)
{
foreach(bool b in values)
{
Console.Write(b ? '1' : '0');
}
Console.WriteLine();
}
}

No reversal there.

Now, in your case you're using a byte array, not a bool array. You seem
to be assuming that the array you pass into BitArray is treated with
the right-most bool as bit 0, but it's not - it's bit 7. The order of
the bits is the order of the array, which makes sense if you think
about it normally, it's just not the way we usually look at bits in a
byte (which is fine, as this is a sequence of bits, it's not a byte).
Indeed if you pass in a byte array to the constructor, the order is
preserved.

I believe BitArray.ToArray is doing exactly what it should be doing,
you're just slightly confused as to what the BitArray(bool[])
constructor does.
 
SpookyET said:
CopyTo treats arrays of different types differently, look at the code with
a decompiler.

Yes, I know. That's why I included the last two paragraphs.
Try my code and see for yourself.

I have. The problem is in your interpretation of the constructor taking
boolean parameters, not in CopyTo.
 
Back
Top