have a short, need to extract 8 bits so I can have a char

D

Danny Anderson

Hola!

I have an array of shorts that represents a stream of data. This data is
packed in tight, so certain elements may actually contain data for more
than one variable.

I am to decipher this stream. The first variable packed into this array
happens to be a short, meaning I get away with a simple assignment:
myFirstVariable=myArray[0];

My problem is that mySecondVariable is a char. What that means is that
the char I need is making up 50% of myArray[1].

How can I get those 8 bits, and only those 8 bits? This is a pretty big
sticking point, because it follows naturally that myThirdVariable starts
in the second half of myArray[1]. In attempting to come up with the right
answer from this datastream, I have tried all kinds of crazy,
groping-in-the-dark kinds of casts, etc., obviously without any luck.

My new tact is going to be trying division, or, along the same vein,
bitwise operations on myArray[1] in an attempt to get my 8 bits. Am I
heading down the right path? If not, would some kind soul steer me
towards the light?


Any help or suggestions much appreciated!

Danny
 
P

Peter van Merkerk

I have an array of shorts that represents a stream of data. This data
is
packed in tight, so certain elements may actually contain data for more
than one variable.

I am to decipher this stream. The first variable packed into this array
happens to be a short, meaning I get away with a simple assignment:
myFirstVariable=myArray[0];

My problem is that mySecondVariable is a char. What that means is that
the char I need is making up 50% of myArray[1].

How can I get those 8 bits, and only those 8 bits? This is a pretty big
sticking point, because it follows naturally that myThirdVariable starts
in the second half of myArray[1]. In attempting to come up with the right
answer from this datastream, I have tried all kinds of crazy,
groping-in-the-dark kinds of casts, etc., obviously without any luck.

My new tact is going to be trying division, or, along the same vein,
bitwise operations on myArray[1] in an attempt to get my 8 bits. Am I
heading down the right path? If not, would some kind soul steer me
towards the light?

That problem can be solved, but to solve it some additional information
is needed. If the data in the stream is a short (I assume that is a
16-bit integer on your platform), does the most significant byte come
first or last?
 
D

Danny Anderson

That problem can be solved, but to solve it some additional information
is needed. If the data in the stream is a short (I assume that is a
16-bit integer on your platform), does the most significant byte come
first or last?
first
 
K

Kevin Saff

Danny Anderson said:
Hola!

I have an array of shorts that represents a stream of data. This data is
packed in tight, so certain elements may actually contain data for more
than one variable.

It sounds like you'd rather have a char array, then, not really a short
array. You should cast the array to chars where they'll be easier to mess
with.
My problem is that mySecondVariable is a char. What that means is that
the char I need is making up 50% of myArray[1].

With a char array, you can get the initial short by casting myArray[0] to a
short, then you've got the char you want at myArray[2]. This might be a
problem if you have a short off of word boundaries, but then I think a
stringstream may satisfy your needs, without too much work.
My new tact is going to be trying division, or, along the same vein,
bitwise operations on myArray[1] in an attempt to get my 8 bits. Am I
heading down the right path? If not, would some kind soul steer me
towards the light?

I think I'd try a stringstream for this, just:
 
M

Mark K

Danny Anderson said:
Hola!

I have an array of shorts that represents a stream of data. This data is
packed in tight, so certain elements may actually contain data for more
than one variable.

I am to decipher this stream. The first variable packed into this array
happens to be a short, meaning I get away with a simple assignment:
myFirstVariable=myArray[0];

My problem is that mySecondVariable is a char. What that means is that
the char I need is making up 50% of myArray[1].

How can I get those 8 bits, and only those 8 bits? This is a pretty big
sticking point, because it follows naturally that myThirdVariable starts
in the second half of myArray[1]. In attempting to come up with the right
answer from this datastream, I have tried all kinds of crazy,
groping-in-the-dark kinds of casts, etc., obviously without any luck.


char firstByteData = (myArray[1] & 0xFF00 ) >> 8;
char secondByteData = (myArray[1] & 0x00FF) ;
 
S

Samuel Barber

Danny Anderson said:
I have an array of shorts that represents a stream of data. This data is
packed in tight, so certain elements may actually contain data for more
than one variable.

I am to decipher this stream. The first variable packed into this array
happens to be a short, meaning I get away with a simple assignment:
myFirstVariable=myArray[0];

My problem is that mySecondVariable is a char. What that means is that
the char I need is making up 50% of myArray[1].

How can I get those 8 bits, and only those 8 bits? This is a pretty big
sticking point, because it follows naturally that myThirdVariable starts
in the second half of myArray[1]. In attempting to come up with the right
answer from this datastream, I have tried all kinds of crazy,
groping-in-the-dark kinds of casts, etc., obviously without any luck.


char firstByteData = (myArray[1] & 0xFF00 ) >> 8;
char secondByteData = (myArray[1] & 0x00FF) ;

Congratulations, you hit on the worst possible method.

Solutions are:

(a) If layout is static, use a struct:
struct mystruct
{
short myFirstVariable;
char mySecondVariable;
char myThirdVariable;
};
(substitute appropriate size-specific typedefs for the C types)

mystruct *myArray = ...
char mySecondVariable = myArray.mySecondVariable;
char myThirdVariable = myArray.myThirdVariable;

(b) Else cast the short* to char*:
short *myArray = ...
char mySecondVariable = * (char*) (myArray+i) ;
char myThirdVariable = * (((char*) (myArray+i))+1) ;

This is the C cast syntax, which also works in C++.

Sam
 
M

Michael Winter

on 14 Oct 03:
(e-mail address removed) (Mark K) wrote in message
"Danny Anderson" <[email protected]> wrote in message
I have an array of shorts that represents a stream of data. This data is
packed in tight, so certain elements may actually contain data for more
than one variable.

I am to decipher this stream. The first variable packed into this array
happens to be a short, meaning I get away with a simple assignment:
myFirstVariable=myArray[0];

My problem is that mySecondVariable is a char. What that means is that
the char I need is making up 50% of myArray[1].

How can I get those 8 bits, and only those 8 bits? This is a pretty big
sticking point, because it follows naturally that myThirdVariable starts
in the second half of myArray[1]. In attempting to come up with the right
answer from this datastream, I have tried all kinds of crazy,
groping-in-the-dark kinds of casts, etc., obviously without any
luck.


char firstByteData = (myArray[1] & 0xFF00 ) >> 8;
char secondByteData = (myArray[1] & 0x00FF) ;

Congratulations, you hit on the worst possible method.

Solutions are:

(a) If layout is static, use a struct:
struct mystruct
{
short myFirstVariable;
char mySecondVariable;
char myThirdVariable;
};
(substitute appropriate size-specific typedefs for the C types)

mystruct *myArray = ...
char mySecondVariable = myArray.mySecondVariable;
char myThirdVariable = myArray.myThirdVariable;

(b) Else cast the short* to char*:
short *myArray = ...
char mySecondVariable = * (char*) (myArray+i) ;
char myThirdVariable = * (((char*) (myArray+i))+1) ;

This is the C cast syntax, which also works in C++.

Sam


Care to _explain_ why bit manipulation is so bad, rather than just
dismissing it?

Would I be right in assuming that your objections revolve around
memory organisation across various architectures? If that's the case,
then it's hardly a reason, the programmer just has to make sure that
data enters the stream in the correct order no matter what machine
it's executed on. I'd much prefer bitwise operations to your second
solution; it's clearer (if properly documented).

Mike
 
B

Big Brian

struct mystruct
{
short myFirstVariable;
char mySecondVariable;
char myThirdVariable;
};
(substitute appropriate size-specific typedefs for the C types)

mystruct *myArray = ...
char mySecondVariable = myArray.mySecondVariable;
char myThirdVariable = myArray.myThirdVariable;


10 lines of code.

short *myArray = ...
char mySecondVariable = * (char*) (myArray+i) ;
char myThirdVariable = * (((char*) (myArray+i))+1) ;

hard to read casts and pointer arithmetic.


I don't see why
char firstByteData = (myArray[1] & 0xFF00 ) >> 8;
char secondByteData = (myArray[1] & 0x00FF) ;

is any worse than the first two. It seems much more obvious what it's
doing than your second solution.


-Brian
 
S

Samuel Barber

Michael Winter said:
on 14 Oct 03:
(e-mail address removed) (Mark K) wrote in message
"Danny Anderson" <[email protected]> wrote in message
I have an array of shorts that represents a stream of data. This data is
packed in tight, so certain elements may actually contain data for more
than one variable.

I am to decipher this stream. The first variable packed into this array
happens to be a short, meaning I get away with a simple assignment:
myFirstVariable=myArray[0];

My problem is that mySecondVariable is a char. What that means is that
the char I need is making up 50% of myArray[1].

How can I get those 8 bits, and only those 8 bits? This is a pretty big
sticking point, because it follows naturally that myThirdVariable starts
in the second half of myArray[1]. In attempting to come up with the right
answer from this datastream, I have tried all kinds of crazy,
groping-in-the-dark kinds of casts, etc., obviously without any luck.


char firstByteData = (myArray[1] & 0xFF00 ) >> 8;
char secondByteData = (myArray[1] & 0x00FF) ;

Congratulations, you hit on the worst possible method.
Would I be right in assuming that your objections revolve around
memory organisation across various architectures?

That's the main reason, yes. It's an unnatural endian dependence,
which screams "bug".
If that's the case,
then it's hardly a reason, the programmer just has to make sure that
data enters the stream in the correct order no matter what machine
it's executed on.

How do you propose to accomplish that? Sounds complicated. Anyway,
it's way outside the scope of the problem description.
I'd much prefer bitwise operations to your second
solution; it's clearer (if properly documented).

Wow.

Sam
 
S

Samuel Barber

struct mystruct
{
short myFirstVariable;
char mySecondVariable;
char myThirdVariable;
};
(substitute appropriate size-specific typedefs for the C types)

mystruct *myArray = ...
char mySecondVariable = myArray.mySecondVariable;
char myThirdVariable = myArray.myThirdVariable;


10 lines of code.


You don't like self-documenting code?
hard to read casts and pointer arithmetic.

If you don't like that syntax (I agree it's a little messy), you can
write it like this:
char *cmyArray = (char*) &myArray;
char mySecondVariable = cmyArray[0];
char myThirdVariable = cmyArray[1];

Sam
 
N

Niklas Borson

[snip]

char firstByteData = (myArray[1] & 0xFF00 ) >> 8;
char secondByteData = (myArray[1] & 0x00FF) ;

If myArray[1] is a signed type then the first statement
above performes a signed shift, which is NOT what you
want. You could solve this by casting to an unsigned
type before shifting. Better yet, create a couple of
helper functions to do the bit fiddling. This makes
the code more self-documenting.

inline unsigned char HighByte(unsigned short w)
{
return w >> 8;
}

inline unsigned char LowByte(unsigned short w)
{
return w & 0x00FF;
}
 

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

No members online now.

Forum statistics

Threads
474,145
Messages
2,570,824
Members
47,371
Latest member
Brkaa

Latest Threads

Top