BitArray MyProblem Or Bug ?  
Author Message
Hamed JI





PostPosted: .NET Base Class Library, BitArray MyProblem Or Bug ? Top

My Problem is BitArray (System.Collentions.BitArray)

if you run the code below

byte[] bits = new byte[2];

bits[0] = 1;

bits[1] = 3;

BitArray BA = new BitArray(bits);

string st = string.Empty;

for(int i=0; i< 16; i++)

st += Convert.ToInt16(BA.Get(i)).ToString();

MessageBox.Show(st);

the code will create byte array with to bytes

first byte will be: "00000001"(binary view of 1) and the second: "00000011" (binary view of 3)

and the we add this two byte to a bitarray the result of bitArray will be "1000000011000000" as you can see BitArray Class invese the bytes "10000000" ( IS NOT BINARY VIEW OF 1) and "11000000" (is not binary view of 3)

as you can see if you inverse all the BA (BitArray) it will be "0000001100000001" And it's not our number either

i don't know if it's bug or there other way to creating BitArray class. i have runed the code in both VS.NET 2003 And VS.NET 2005 even in VB both the result is the sam




.NET Development14  
 
 
Alex Farber





PostPosted: .NET Base Class Library, BitArray MyProblem Or Bug ? Top

Read MSDN topic BitArray Constructor (Byte[]):

The first byte in the array represents bits 0 through 7, the second byte represents bits 8 through 15, and so on.

You can see that bytes are added to bit array in the reverse order.


 
 
nobugz





PostPosted: .NET Base Class Library, BitArray MyProblem Or Bug ? Top

Alex is quite correct about the order in which the bits are stored in the byte[] but that is the not the specific problem here. You just need to change your for() statement to:
for(int i=15; i >= 0; --i)
You want to display bit #15 first and bit #0 last.



 
 
Hamed JI





PostPosted: .NET Base Class Library, BitArray MyProblem Or Bug ? Top

as i said using "for(int i = 15; i>=0; i--)" won't solve the problem.

if you look closer you'll see the "for" you wrote will produce "0000001100000001" but the true bits are: "0000000100000011".

Constructor first use the first byte and then use second byte it's true but inverse them it's false.



 
 
nobugz





PostPosted: .NET Base Class Library, BitArray MyProblem Or Bug ? Top

Oops, Alex was correct. Intel/AMD CPUs are little-endian.




 
 
Hamed JI





PostPosted: .NET Base Class Library, BitArray MyProblem Or Bug ? Top

Thank's nobugz for his link

but if it's the problem of this class. it can produce more bigger problems

for example when you save a long(int64) value and load it as two int32 or 4 bytes your data will broke completly you save one think and you load another think completly diffrent with what you have saved



 
 
nobugz





PostPosted: .NET Base Class Library, BitArray MyProblem Or Bug ? Top

Sure, you can't really expect to not see a value change when you save it as one type and load it as another. Alex was yet again correct to point out that what you saw is a quirk about how the BitArray(Byte[]) constructor works. Little-endian is very forgiving when it comes to reading a memory location using different types.

Perhaps a better way to demonstrate this is by using a union. Visual Basic doesn't really support it but can be tricked. For example:
Imports System.Runtime.InteropServices
....
<StructLayout(LayoutKind.Explicit)> _
Private Structure Union
<FieldOffset(0)> Public lval As Long
<FieldOffset(0)> Public ival1 As Integer
<FieldOffset(4)> Public ival2 As Integer
End Structure
...
Dim test As Union
test.lval = &H123456789ABCDEF0

Here, the lval member takes 8 bytes at memory offset 0, ival1 is overlapped with the first 4 bytes at offset 0 and ival2 is overlapped with the next 4 bytes at offset 4. If we stick a big number in lval (say: lval = &H123456789ABCDEF0), you'll see that ival1 contains &H9ABCDEF0, the 4 least significant bytes in the value of lval, and ival2 contains &H12345678. Keep a small number in there, small enough to only require 4 bytes (say: lval = &H76543210), ival1 has the "correct" value and ival2 is 0.

If you would run the same test on a big-endian CPU, you'd probably see the reverse. You can't run this test because .NET doesn't run on any big-endian CPU that I'm aware of. Endian-ness is rarely a problem in normal programming tasks. You should generally not count on it to avoid future portability problems. As unlikely that sounds now that Apple has started using Intel CPUs...



 
 
Hamed JI





PostPosted: .NET Base Class Library, BitArray MyProblem Or Bug ? Top

I have write my own BitArray Class

http://www.codeproject.com/useritems/JIBitArray.asp



 
 
Anibal Acosta





PostPosted: .NET Base Class Library, BitArray MyProblem Or Bug ? Top

Bit order depend of the processor. You must convert the order only if the processor use little endian.

Try this to convert from int16 and from bigendian 

public static Byte[] FromInt16ToByteArray(Int16 number)
{
Byte[] ouByte = BitConverter.GetBytes(number);
if (BitConverter.IsLittleEndian) { Array.Reverse(ouByte); }

return ouByte;
}

public static Int16 FromByteArrayToInt16(Byte[] number)
{
if (BitConverter.IsLittleEndian) { Array.Reverse(number); }

return BitConverter.ToInt16(number,0);
}