# Reading bits at an offset

Discussion in 'C++' started by pedagani@gmail.com, Nov 30, 2005.

1. ### Guest

Problem: read 'nBits' (where 0< nbits <= 32) from a buffer
'buffer[1024]' at a byte position 'pos' with a *bit* offset value of
'bitOffset'. Below is the code that does that (not tested for errors),
but was wondering if there is any better way of implementing the same.
Thank you.
-KK

//Step 1 - read the rest of the bits in the first byte
std::bitset< 8 > firstByte(buffer[pos]);
for ( int i = 0; i < bitOffset ; i++ )
firstByte = 0;
this->val = T (firstByte.to_ulong() << nBits);
int nBitsReadSoFar = (8 - bitOffset);

if ( nBits < nBitsReadSoFar ) //throw away extra bits
{
val >>= (nBitsReadSoFar - nBits);
nBitsReadSoFar = nBits;
return val;
}

//step 2: read integral number of bytes over which the bits are spread
int nIntegralBytes = (nBits - nBitsReadSoFar)/8;
unsigned long int acc = 0;
for ( int i = 0; i < nIntegralBytes; i++ )
{
acc |= ( buffer[pos + 1 + i] << ( (nIntegralBytes -1 - i) *8) );
nBitsReadSoFar += 8;
}
acc <<= nBits - nBitsReadSoFar;

//step 3: read rest of bits in the last byte
std::bitset< 8 > lastByte(buffer[pos + nIntegralBytes + 1]);
for ( int i = (nBits - nBitsReadSoFar); i < 8 ; i++ )
lastByte=0;
lastByte >>= (8 - (nBits - nBitsReadSoFar) );

//step 4 - club all the pieces of bitsets into one
val = ((firstByte.to_ulong() << nBits)| acc ) | lastByte.to_ulong();
return val;

, Nov 30, 2005

2. ### Guest

wrote:
> Problem: read 'nBits' (where 0< nbits <= 32) from a buffer
> 'buffer[1024]' at a byte position 'pos' with a *bit* offset value of
> 'bitOffset'. Below is the code that does that (not tested for errors),
> but was wondering if there is any better way of implementing the same.
> Thank you.
> -KK
>
> //Step 1 - read the rest of the bits in the first byte
> std::bitset< 8 > firstByte(buffer[pos]);
> for ( int i = 0; i < bitOffset ; i++ )
> firstByte = 0;
> this->val = T (firstByte.to_ulong() << nBits);
> int nBitsReadSoFar = (8 - bitOffset);
>
> if ( nBits < nBitsReadSoFar ) //throw away extra bits
> {
> val >>= (nBitsReadSoFar - nBits);
> nBitsReadSoFar = nBits;
> return val;
> }
>
> //step 2: read integral number of bytes over which the bits are spread
> int nIntegralBytes = (nBits - nBitsReadSoFar)/8;
> unsigned long int acc = 0;
> for ( int i = 0; i < nIntegralBytes; i++ )
> {
> acc |= ( buffer[pos + 1 + i] << ( (nIntegralBytes -1 - i) *8) );
> nBitsReadSoFar += 8;
> }
> acc <<= nBits - nBitsReadSoFar;
>
>
> //step 3: read rest of bits in the last byte
> std::bitset< 8 > lastByte(buffer[pos + nIntegralBytes + 1]);
> for ( int i = (nBits - nBitsReadSoFar); i < 8 ; i++ )
> lastByte=0;
> lastByte >>= (8 - (nBits - nBitsReadSoFar) );
>
> //step 4 - club all the pieces of bitsets into one
> val = ((firstByte.to_ulong() << nBits)| acc ) | lastByte.to_ulong();
> return val;

the fourth line in the code should have been
val =(firstByte.to_ulong() << nBits);
instead of
this->val = T (firstByte.to_ulong() << nBits);

, Nov 30, 2005

3. ### Guest

My colleague has found the solution for me: here I'm posting it, just
for archives
*not a tested code*
On windows platform use
__int64 acc=0;
for( int i = 0; i < 5; i++ )
{
__int64 tmp = buffer[ pos + i ] << ( (7 - i) *8 );
acc |= tmp;
}
acc <<= bitOffset;
acc >>= (64- nBits);
val = unsigned long int (acc);
for UNIX replacing __int64 with long long should help I guess

, Dec 1, 2005

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.