Reading bits off an unsiged long

S

Simon

Hi,

I am reading a file that contains a bunch of unsigned longs.
The number itself is broken down in bits, for example

bit 31-24 is a certain code and bit 7-6 represents a certain state.

am I right in doing the following

// read the unsigned long from the file
unsigned long ulDataFromFile = 0;
/*
... read it
*/
// define some values, code and state
unsigned short usCode = 0; // size = 7 'cause we are reading bit 31-24
unsigned char ucState = 0; // size = 1 'cause we are reading bit 7-6

// use the unsigned long to read the data itself.
memcpy( &usCode, ((unsigned char*)ulDataFromFile)+24, sizeof(unsigned
char) ); // read bit 31-24
memcpy( &ucState , ((unsigned char*)ulDataFromFile)+7, sizeof(unsigned
short ) ); // read bit 7-6

Am I right?

I cannot really test the data as I am not sure what values to expect inside
the unsigned long

Many thanks in advance.

Simon
 
M

Malte Starostik

Simon said:
Hi,

I am reading a file that contains a bunch of unsigned longs.
The number itself is broken down in bits, for example

bit 31-24 is a certain code and bit 7-6 represents a certain state.

am I right in doing the following

// read the unsigned long from the file
unsigned long ulDataFromFile = 0;
/*
... read it
*/
// define some values, code and state
unsigned short usCode = 0; // size = 7 'cause we are reading bit 31-24
unsigned char ucState = 0; // size = 1 'cause we are reading bit 7-6
The actual sizes don't matter as long as they're large enough to hold
the value. BTW, an unsigned char is still enough to hold 7 bits...
// use the unsigned long to read the data itself.
memcpy( &usCode, ((unsigned char*)ulDataFromFile)+24, sizeof(unsigned
char) ); // read bit 31-24
No, this reads a byte from 24 *bytes* after the start of ulDataFromFile:
undefined behavious
memcpy( &ucState , ((unsigned char*)ulDataFromFile)+7, sizeof(unsigned
short ) ); // read bit 7-6
Similarly here.
Am I right?
I'm afraid you aren't.
// right shift by 24 bits to discard bits 0-23
// then mask out anything beyond bit 31 (which is now bit 7)
usCode = ( ulDataFromFile >> 24 ) & 0xff;
// right shift by 6 bits to discard bits 0-5
// then mask out anything beyond bit 7 (which is now bit 1)
ucState = ( ulDataFromFile >> 6 ) & 0x03;
I cannot really test the data as I am not sure what values to expect inside
the unsigned long
You can easily try by setting ulDataFromFile to a made-up value and
compare the results to what you'd expect...
e.g. if ulDataFromFile is 0x12345678, usCode must afterwards be 0x12 and
ucState must be 0x01

HTH,
Malte
 
J

John Carson

Simon said:
Hi,

I am reading a file that contains a bunch of unsigned longs.
The number itself is broken down in bits, for example

bit 31-24 is a certain code and bit 7-6 represents a certain state.

am I right in doing the following

// read the unsigned long from the file
unsigned long ulDataFromFile = 0;
/*
... read it
*/
// define some values, code and state
unsigned short usCode = 0; // size = 7 'cause we are reading
bit 31-24 unsigned char ucState = 0; // size = 1 'cause we are
reading bit 7-6

// use the unsigned long to read the data itself.
memcpy( &usCode, ((unsigned char*)ulDataFromFile)+24, sizeof(unsigned
char) ); // read bit 31-24
memcpy( &ucState , ((unsigned char*)ulDataFromFile)+7,
sizeof(unsigned short ) ); // read bit 7-6

Am I right?

I cannot really test the data as I am not sure what values to expect
inside the unsigned long

Many thanks in advance.

Simon

Try this:

#include <cmath>

class BitExtractor
{
public:
BitExtractor(unsigned long data) : databits(data)
{}

unsigned long Extract(size_t lowBit, size_t highBit) const
{
int digitCount = highBit - lowBit + 1;
unsigned long mask = (unsigned long)pow((int)2, digitCount) - 1;
return (databits>>lowBit) & mask;
}
private:
unsigned long databits;
};


Use it as follows:

BitExtractor be(ulDataFromFile);

// to get bits from index 6 to 7

unsigned long six_to_seven = be.Extract(6,7);

// to get bits from index 24 to 31

unsigned long twentyfour_to_thirtyone = be.Extract(24,31);
 
O

Old Wolf

Malte said:
No, this reads a byte from 24 *bytes* after the start of
ulDataFromFile: undefined behavious

That would be: ((unsigned char *)&ulDataFromFile)+24 . The OP code
is far worse than that.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,202
Messages
2,571,057
Members
47,662
Latest member
sxarexu

Latest Threads

Top