0

As input I get an int (well, actually a string I should convert to an int).
This int should be converted to bits.
For each bit position that has a 1, I should get the position.
In my database, I want all records that have an int value field that has this position as value.
I currently have the following naive code that should ask my entity(holding the databaseValue) if it matches the position, but obviously doesn't work correctly:

Byte[] bits = BitConverter.GetBytes(theDatabaseValue);
return bits[position].equals(1);

Firstly, I have an array of byte because there apparantly is no bit type. Should I use Boolean[] ? Then, how can I fill this array? Lastly, if previous statements are solved, I should just return bits[position]

I feel like this should somehow be solved with bitmasks, but I don't know where to start..

Any help would be appreciated

Boris Callens
  • 90,659
  • 85
  • 207
  • 305

3 Answers3

4

I suspect BitArray is what you're after. Alternatively, using bitmasks yourself isn't hard:

for (int i=0; i < 32; i++)
{
    if ((value & (1 << i)) != 0)
    {
        Console.WriteLine("Bit {0} was set!", i);
    }
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
4

Your feeling is correct. This should be solved with bitmasks. BitConverter does not return bits (and how could it? "bits" isn't an actual data type), it converts raw bytes to CLR data types. Whenever you want to extract the bits out of something, you should think bitmasks.

If you want to check if a bit at a certain position is set, use the & operator. Bitwise & is only true if both bits are set. For example if you had two bytes 109 and 33, the result of & would be

  0110 1101
& 0010 0001
-----------
  0010 0001

If you just want to see if a bit is set in an int, you & it with a number that has only the bit you're checking set (ie 1, 2, 4, 8, 16, 32 and so forth) and check if the result is not zero.

List<int> BitPositions(uint input) {
    List<int> result = new List<int>();
    uint mask = 1;
    int position = 0;
    do {
        if (input & mask != 0) {
            result.Add(position);
        }
        mask <<= 1;
        position++;
    } while (mask != 0);

    return result;
}
Tmdean
  • 9,108
  • 43
  • 51
  • But still I wonder why the called it BitConverter when actually it is a ByteConverter... – Boris Callens Dec 17 '08 at 16:09
  • That's a good question, but you can probably imagine that the name "ByteConverter" would cause a different kind of confusion. – Tmdean Dec 17 '08 at 16:19
  • Well, it doesn't _really_ convert bytes, it converts arrays of bytes, and it's only using the bytes as a convenient representation of raw bits. The name "ByteConverter" doesn't really give you a sense of what the class does. – Tmdean Dec 17 '08 at 16:34
1

Do not use Boolean. Although boolean has only two values, it is actually stored using 32 bits like an int.

EDIT: Actually, in array form Booleans will be packed into bytes, not 4 bytes.

Szymon Rozga
  • 17,971
  • 7
  • 53
  • 66
  • Not in an array it's not. Nor if you have several boolean fields - they'll (by default, at least) get packed together. Not into single bits, admittedly - but each will only take a single byte, rather than 4. If you have a single boolean field and then an int field, padding will kick in, of course. – Jon Skeet Dec 17 '08 at 15:57
  • Yes, that's what I figured. But I'm a bit wandering in the dark here so anything will do :P Currently trying to 1UP my bitskills ;) – Boris Callens Dec 17 '08 at 15:57
  • He, and once again I leech some of Jon's knowledge :P – Boris Callens Dec 17 '08 at 15:58
  • (Basically using a Boolean is equivalent to using a Byte in terms of memory usage.) – Jon Skeet Dec 17 '08 at 15:59