Velocity Reviews > C++ > Reading bits at an offset

# Reading bits at an offset

pedagani@gmail.com
Guest
Posts: n/a

 11-30-2005
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[i] = 0;
this->val = T (firstByte.to_ulong() << nBits);
int nBitsReadSoFar = (8 - bitOffset);

if ( nBits < nBitsReadSoFar ) //throw away extra bits
{
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) * );
}

//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[i]=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;

pedagani@gmail.com
Guest
Posts: n/a

 11-30-2005
http://www.velocityreviews.com/forums/(E-Mail Removed) 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[i] = 0;
> this->val = T (firstByte.to_ulong() << nBits);
> int nBitsReadSoFar = (8 - bitOffset);
>
> if ( nBits < nBitsReadSoFar ) //throw away extra bits
> {
> val >>= (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) * );
> }
> 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[i]=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);
this->val = T (firstByte.to_ulong() << nBits);

pedagani@gmail.com
Guest
Posts: n/a

 12-01-2005
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