3

I have two bytes containing a 14-bit left-justified two's complement value, and I need to convert it to a signed short value (ranging from -8192 to +8191, I guess?)

What would be the fastest way to do that?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Maestro
  • 9,046
  • 15
  • 83
  • 116

2 Answers2

4

Simply divide by 4.

(Note, right-shift leads to implementation/undefined behaviour.)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
1

A portable solution:

short convert(unsigned char hi, unsigned char lo)
{
  int s = (hi << 6) | (lo >> 2);
  if (s >= 8192)
    s -= 16384;
  return s;
}
Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
  • I do: x = ((int16_t)((byte[0] << 8) | byte[1]) / 4) now, which seems to work fine. Is your solution more portable of faster? – Maestro Feb 05 '13 at 17:08
  • Which is faster depends on the compiler. Yours exhibits undefined behavior by overflowing a signed integer type, int16_t. – Alexey Frunze Feb 05 '13 at 17:16
  • @AlexeyFrunze That won't compile, you've mis-matched the argument names (`lo` vs `low`). – unwind Apr 10 '13 at 11:53
  • @unwind Love it when fixing the code means deleting a part of it, even if a single character. :) – Alexey Frunze Apr 10 '13 at 11:57