Fernando Aires Castello
Fernando Aires Castello

Reputation: 1243

How to extract 2 bytes from a word, and how to make a word from 2 bytes (in C)?

I am trying to extract two bytes from a 16-bit word, and to make a 16-bit word from two bytes. This is what I have tried (byte = unsigned char, word = unsigned short):

Split grpix word into 2 bytes:

word grpix; // Assume that the value has been initialized

byte grpixl = grpix & 0x00FF;
byte grpixh = grpix & 0xFF00;

Make grpix word from 2 bytes

byte grpixh; // Assume that the value has been initialized
byte grpixl; // Assume that the value has been initialized

word grpix = grpixh;
grpix <<= 8;
grpix += grpixl;

For some reason, my code doesn't work as expected, and now I'm not sure if the "splitting" of the word is wrong, if the "making" of the word is wrong, or both... Could you give me some advice?

Upvotes: 2

Views: 23772

Answers (6)

Ian McMahon
Ian McMahon

Reputation: 1700

When you mask out the high byte, you need to also shift down by 8 bits, otherwise you just end up with a 16bit number with the bottom eight bits cleared.

byte grpixh = (grpix & 0xFF00) >> 8

Also your composition can be more efficient by using or-equals instead of plus-equals:

grpix |= grpixh << 8

Upvotes: 0

DJ JAG
DJ JAG

Reputation: 11

word grpix = grpixl+256*grpixh;

Upvotes: -1

user6743474
user6743474

Reputation:

The following routines have proved very reliable for me:-

unsigned short get16int(a) char *a;{
   unsigned short hi,lo;
   hi = *a++ << 8;
   lo = *a  & 0x00ff; /* Needed to cater for sign extending when msb bit is set */
   return (hi | lo);
}
put16int(a,i) char *a; int i;{
 *a++ = i >> 8;
 *a = i;
}

Upvotes: 0

mohammad
mohammad

Reputation: 1

The simple code that I use to solve this, is:

word=(msb<<8)+lsb;

Upvotes: 0

Gilbert
Gilbert

Reputation: 3776

Get to know: http://graphics.stanford.edu/~seander/bithacks.html for doing all manner of operations.

right_byte = short_val & 0xFF;
left_byte = ( short_val >> 8 ) & 0xFF

short_val = ( ( left_byte & 0xFF ) << 8 ) | ( right_byte & 0xFF );

I always do a &0xFF mask to assure I have no sign problems.

Upvotes: 4

Lily Ballard
Lily Ballard

Reputation: 185741

You're not shifting when you split the word. So if grpix is 0x1234, then grpixl gets the expected 0x34 but grpixh ends up as 0x1200. You should say

byte grpixh = grpix >> 8;

Of course, you're also ignoring any endianness concerns that may be present. You should probably convert your word to a known endian (with something like htons()) before attempting to split (and do the reverse conversion when joining).

Upvotes: 6

Related Questions