user2894356
user2894356

Reputation: 139

Casting two bytes to a 12 bit short value?

I have a buffer which consists of data in unsigned char and two bytes form a 12 Bit value.

I found out that my system is little endian. The first byte in the buffer gives me on the console numbers from 0 to 255. The second byte gives always low numbers between 1 and 8 (measured data, so higher values up to 4 bit would be possible too).

I tried to shift them together so that I get an ushort with a correct 12 bit number.

Sadly at the moment I am totally confused about the endianess and what I have to shift how far in which direction.

I tried e.g. this:

ushort value =0;
value= (ushort) firstByte << 8 | (ushort) secondByte << 4;

Sadly the value of value is quite often bigger than 12 bit.

Where is the mistake?

Upvotes: 0

Views: 582

Answers (2)

Paul R
Paul R

Reputation: 212949

It depends on how the bits are packed within the two bytes exactly, but the solution for the most likely packing would be:

value = firstByte | (secondByte << 8);

This assumes that the second byte contains the 4 most significant bits (bits 8..11), while the first byte contains the 8 least significant bits (bits 0..7).


Note: the above solution assumes that firstByte and secondByte are sensible unsigned types (e.g. uint8_t). If they are not (e.g. if you have used char or some other possibly signed type), then you'll need to add some masking:

value = (firstByte & 0xff) | ((secondByte & 0xf) << 8);

Upvotes: 6

Nova Ardent
Nova Ardent

Reputation: 161

I think the main issue may not be with the values you're shifting alone. If these values are greater than their representative bits, they'll create a large value unless "and'd" out.

picture the following

0000 0000 1001 0010 << 8 | 0000 0000 0000 1101 << 4
1001 0010 0000 0000 | 0000 0000 1101 0000

You should notice the first problem here. The first 4 'lowest' values are not being used, and it's using up 16 bits. you only wanted twelve. This should be modified like so:

(these are new numbers to demonstrate something else)
0000 1101 1001 0010 << 8 | 0000 0000 0000 1101
1101 1001 0010 0000 | (0000 0000 0000 1101 & 0000 0000 0000 1111)

This will create the following value:

1101 1001 0010 1101 

here, you should note that the value is still greater than the 12 bits. If your numbers don't extend passed the original 8bit, 4 bit size ignore this. Otherwise, you have to use the 'and' operation on the bits to eliminate the left most 4 bits.

0000 1111 1111 1111 & 0000 1001 0010 1101

These values can be created using either 0bXX macros, the 2^bits - 1 pattern, as well as various other forms.

Upvotes: 0

Related Questions