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

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.
 
G

Guest

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
 
J

Jon Skeet [C# MVP]

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.
 
S

SpookyET

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.
 
J

Jon Skeet [C# MVP]

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top