Connecting Tech Pros Worldwide Forums | Help | Site Map

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

Danny Anderson
Guest
 
Posts: n/a
#1: Jul 19 '05
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

Peter van Merkerk
Guest
 
Posts: n/a
#2: Jul 19 '05

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


> I have an array of shorts that represents a stream of data. This data
is[color=blue]
> packed in tight, so certain elements may actually contain data for[/color]
more[color=blue]
> than one variable.
>
> I am to decipher this stream. The first variable packed into this[/color]
array[color=blue]
> 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[/color]
that[color=blue]
> 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[/color]
big[color=blue]
> sticking point, because it follows naturally that myThirdVariable[/color]
starts[color=blue]
> in the second half of myArray[1]. In attempting to come up with the[/color]
right[color=blue]
> 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?[/color]

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?

--
Peter van Merkerk
peter.van.merkerk(at)dse.nl


Danny Anderson
Guest
 
Posts: n/a
#3: Jul 19 '05

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


[color=blue]
> 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?
>
> --
> Peter van Merkerk
> peter.van.merkerk(at)dse.nl[/color]
first
Kevin Saff
Guest
 
Posts: n/a
#4: Jul 19 '05

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



"Danny Anderson" <bturnip@i.hate.spam> wrote in message
news:pan.2003.10.13.06.57.59.594405@i.hate.spam...[color=blue]
> 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.[/color]

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.
[color=blue]
> My problem is that mySecondVariable is a char. What that means is that
> the char I need is making up 50% of myArray[1].[/color]

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.
[color=blue]
> 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?[/color]

I think I'd try a stringstream for this, just:
[color=blue]
>
>
> Any help or suggestions much appreciated!
>
> Danny[/color]


Mark K
Guest
 
Posts: n/a
#5: Jul 19 '05

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


"Danny Anderson" <bturnip@i.hate.spam> wrote in message news:<pan.2003.10.13.06.57.59.594405@i.hate.spam>. ..[color=blue]
> 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.[/color]


char firstByteData = (myArray[1] & 0xFF00 ) >> 8;
char secondByteData = (myArray[1] & 0x00FF) ;
Samuel Barber
Guest
 
Posts: n/a
#6: Jul 19 '05

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


Mark_Kidd@May-Co.com (Mark K) wrote in message news:<71c70057.0310130915.701d9408@posting.google. com>...[color=blue]
> "Danny Anderson" <bturnip@i.hate.spam> wrote in message news:<pan.2003.10.13.06.57.59.594405@i.hate.spam>. ..[color=green]
> > 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.[/color]
>
>
> char firstByteData = (myArray[1] & 0xFF00 ) >> 8;
> char secondByteData = (myArray[1] & 0x00FF) ;[/color]

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[i].mySecondVariable;
char myThirdVariable = myArray[i].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
Michael Winter
Guest
 
Posts: n/a
#7: Jul 19 '05

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


"Samuel Barber" wrote on 14 Oct 03:
[color=blue]
> Mark_Kidd@May-Co.com (Mark K) wrote in message[/color]
news:<71c70057.0310130915.701d9408@posting.google. com>...[color=blue][color=green]
> > "Danny Anderson" <bturnip@i.hate.spam> wrote in message[/color][/color]
news:<pan.2003.10.13.06.57.59.594405@i.hate.spam>. ..[color=blue][color=green][color=darkred]
> > > I have an array of shorts that represents a stream of data. This[/color][/color][/color]
data is[color=blue][color=green][color=darkred]
> > > packed in tight, so certain elements may actually contain data[/color][/color][/color]
for more[color=blue][color=green][color=darkred]
> > > than one variable.
> > >
> > > I am to decipher this stream. The first variable packed into[/color][/color][/color]
this array[color=blue][color=green][color=darkred]
> > > happens to be a short, meaning I get away with a simple[/color][/color][/color]
assignment:[color=blue][color=green][color=darkred]
> > > myFirstVariable=myArray[0];
> > >
> > > My problem is that mySecondVariable is a char. What that means[/color][/color][/color]
is that[color=blue][color=green][color=darkred]
> > > 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[/color][/color][/color]
pretty big[color=blue][color=green][color=darkred]
> > > sticking point, because it follows naturally that[/color][/color][/color]
myThirdVariable starts[color=blue][color=green][color=darkred]
> > > in the second half of myArray[1]. In attempting to come up with[/color][/color][/color]
the right[color=blue][color=green][color=darkred]
> > > answer from this datastream, I have tried all kinds of crazy,
> > > groping-in-the-dark kinds of casts, etc., obviously without any[/color][/color][/color]
luck.[color=blue][color=green]
> >
> >
> > char firstByteData = (myArray[1] & 0xFF00 ) >> 8;
> > char secondByteData = (myArray[1] & 0x00FF) ;[/color]
>
> 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[i].mySecondVariable;
> char myThirdVariable = myArray[i].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[/color]

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

--
Michael Winter
M.Winter@[no-spam]blueyonder.co.uk (remove [no-spam] to reply)


Big Brian
Guest
 
Posts: n/a
#8: Jul 19 '05

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


> struct mystruct[color=blue]
> {
> short myFirstVariable;
> char mySecondVariable;
> char myThirdVariable;
> };
> (substitute appropriate size-specific typedefs for the C types)
>
> mystruct *myArray = ...
> char mySecondVariable = myArray[i].mySecondVariable;
> char myThirdVariable = myArray[i].myThirdVariable;[/color]

10 lines of code.

[color=blue]
> short *myArray = ...
> char mySecondVariable = * (char*) (myArray+i) ;
> char myThirdVariable = * (((char*) (myArray+i))+1) ;[/color]

hard to read casts and pointer arithmetic.


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

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


-Brian
Samuel Barber
Guest
 
Posts: n/a
#9: Jul 19 '05

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


"Michael Winter" <M.Winter@[no-spam]blueyonder.co.uk> wrote in message news:<qTSib.6596$HA1.57806970@news-text.cableinet.net>...[color=blue]
> "Samuel Barber" wrote on 14 Oct 03:
>[color=green]
> > Mark_Kidd@May-Co.com (Mark K) wrote in message[/color]
> news:<71c70057.0310130915.701d9408@posting.google. com>...[color=green][color=darkred]
> > > "Danny Anderson" <bturnip@i.hate.spam> wrote in message[/color][/color]
> news:<pan.2003.10.13.06.57.59.594405@i.hate.spam>. ..[color=green][color=darkred]
> > > > I have an array of shorts that represents a stream of data. This[/color][/color]
> data is[color=green][color=darkred]
> > > > packed in tight, so certain elements may actually contain data[/color][/color]
> for more[color=green][color=darkred]
> > > > than one variable.
> > > >
> > > > I am to decipher this stream. The first variable packed into[/color][/color]
> this array[color=green][color=darkred]
> > > > happens to be a short, meaning I get away with a simple[/color][/color]
> assignment:[color=green][color=darkred]
> > > > myFirstVariable=myArray[0];
> > > >
> > > > My problem is that mySecondVariable is a char. What that means[/color][/color]
> is that[color=green][color=darkred]
> > > > 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[/color][/color]
> pretty big[color=green][color=darkred]
> > > > sticking point, because it follows naturally that[/color][/color]
> myThirdVariable starts[color=green][color=darkred]
> > > > in the second half of myArray[1]. In attempting to come up with[/color][/color]
> the right[color=green][color=darkred]
> > > > answer from this datastream, I have tried all kinds of crazy,
> > > > groping-in-the-dark kinds of casts, etc., obviously without any[/color][/color]
> luck.[color=green][color=darkred]
> > >
> > >
> > > char firstByteData = (myArray[1] & 0xFF00 ) >> 8;
> > > char secondByteData = (myArray[1] & 0x00FF) ;[/color]
> >
> > Congratulations, you hit on the worst possible method.
> >[/color]
> Would I be right in assuming that your objections revolve around
> memory organisation across various architectures?[/color]

That's the main reason, yes. It's an unnatural endian dependence,
which screams "bug".
[color=blue]
> 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.[/color]

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

Wow.

Sam
Samuel Barber
Guest
 
Posts: n/a
#10: Jul 19 '05

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


work@brianmielke.com (Big Brian) wrote in message news:<d283547.0310140639.208a4542@posting.google.c om>...[color=blue][color=green]
> > struct mystruct
> > {
> > short myFirstVariable;
> > char mySecondVariable;
> > char myThirdVariable;
> > };
> > (substitute appropriate size-specific typedefs for the C types)
> >
> > mystruct *myArray = ...
> > char mySecondVariable = myArray[i].mySecondVariable;
> > char myThirdVariable = myArray[i].myThirdVariable;[/color]
>
> 10 lines of code.[/color]

You don't like self-documenting code?
[color=blue][color=green]
> > short *myArray = ...
> > char mySecondVariable = * (char*) (myArray+i) ;
> > char myThirdVariable = * (((char*) (myArray+i))+1) ;[/color]
>
> hard to read casts and pointer arithmetic.[/color]

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

Sam
Niklas Borson
Guest
 
Posts: n/a
#11: Jul 19 '05

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


Mark_Kidd@May-Co.com (Mark K) wrote in message news:<71c70057.0310130915.701d9408@posting.google. com>...[color=blue]
> [snip]
>
> char firstByteData = (myArray[1] & 0xFF00 ) >> 8;
> char secondByteData = (myArray[1] & 0x00FF) ;[/color]

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;
}
Closed Thread