0

OK, say I have a boolean array called bits, and an int called cursor

I know I can access individual bits by using bits[cursor], and that I can use bit logic to get larger datatypes from bits, for example:

short result = (bits[cursor] << 3) |
    (bits[cursor+1] << 2) | 
    (bits[cursor+2] << 1) |
     bits[cursor+3];

This is going to result in lines and lines of code when reading larger types like int32 and int64 though.

Is it possible to do a cast of some kind and achieve the same result? I'm not concerned about safety at all in this context (these functions will be wrapped into a class that handles that)

Say I wanted to get an uint64_t out of bits, starting at an arbitrary address specified by cursor, when cursor isn't necessarily a multiple of 64; is this possible by a cast? I thought this

uint64_t result = (uint64_t *)(bits + cursor)[0];

Would work, but it doesn't want to compile.

Sorry I know this is a dumb question, I'm quite inexperienced with pointer math. I'm not looking just for a short solution, I'm also looking for a breakdown of the syntax if anyone would be kind enough.

Thanks!

Pez
  • 172
  • 2
  • 15
  • 1
    It depends on how your array is implemented. Most "boolean" array implementations use a byte or word per "bit", so you can't recast the array pointer to a different type and get anything useful. It might be better to make your array an int array and then use bit masking to access at the "boolean" level. (And no common machine implementation will allow you to access a "word" at an odd-bit boundary -- at best you can access at a byte boundary.) – Hot Licks May 28 '13 at 14:42
  • You can't assume that a boolean is a bit. Check limits.h to see what it is for your platform. – Simon May 28 '13 at 14:43
  • Thanks Hot Licks, I can probably write a class to behave in this way! I know that the size of a bool can depend on the implementation, I wasn't aware it was so much of a fiddle to get it to behave this way though. For anyone reading this in the future, please refer to this thread: http://stackoverflow.com/questions/2064550/c-why-bool-is-8-bits-long – Pez May 28 '13 at 17:20

1 Answers1

0

You could try something like this and cast the result to your target data size.

uint64_t bitsToUint64(bool *bits, unsigned int bitCount)
{
    uint64_t result = 0;
    uint64_t tempBits = 0;
    if(bitCount > 0 && bitCount <= 64)
    {
        for(unsigned int i = 0, j = bitCount - 1; i < bitCount; i++, j--)
        {
            tempBits = (bits[i])?1:0;
            result |= (tempBits << j);
        }
    }
    return result;
}
John Sheridan
  • 446
  • 4
  • 8
  • Thanks John, but this isn't ideal for types of an arbitrary size, I'd rather avoid loops as well if possible as this is even more of a performance hit than my first example (whereas I was looking to improve performance with a cast), cheers though this code is noted!! – Pez May 28 '13 at 17:22
  • Cheers John, I used an adaption of this: uint64_t readBits(int count) { uint8_t result = 0; int countMinusOne = count - 1; for(int i = 0; i < count; i++) result |= (_bits[_cursor + i] & 0x1) << (countMinusOne - i); _cursor += count; return result; } – Pez May 29 '13 at 08:25