By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,227 Members | 1,373 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,227 IT Pros & Developers. It's quick & easy.

Reading bits off an unsiged long

P: n/a
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
Jul 23 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Simon schrieb:
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
Jul 23 '05 #2

P: n/a
"Simon" <sp********@myoddweb.com> wrote in message
news:3a*************@individual.net
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);
--
John Carson
Jul 23 '05 #3

P: n/a
<snip>
John Carson


Many thanks John and Malte, I guess I was confused with Bytes and bits.

Simon
Jul 23 '05 #4

P: n/a
Malte Starostik wrote:
Simon schrieb:

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

unsigned long ulDataFromFile = 0;

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


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

Jul 23 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.