 # help with bit shifting?

I'm trying to get my head around some code that uses bit shifting to unpack vector coordinates for HPGL font 'draw + move' instructions. I am using a programming calculator to try to work through the code but I am not getting it.

Description of the data format and the function I am working with is below. The lines I am wrestling with are these two:

``````x = (double) (c >> 4)   - 1.0;      /* Bits 4,5,6 --> value 0..7 */
y = (double) (c & 0x0f) - 4.0;      /* Bits 0-3   --> value 0..f */
``````

To work the problem, according to the data format spec, an input of 324 should result in x == 5, y ==4;

what I get:

(for x) 324 >> 4 is 20; then subtract 1 == 19

then

(for y) 20 AND 15 == 4; then subtract 4 == 0

I have this ass backwards somehow, yes? ;-)

Data format:

``````** A font or character set is an array of strings. Each character
** corresponds to one of these strings, which is addressed by its ASCII code.
**
** A character is a (NULL-terminated) string of bytes. Each byte
** codes for a draw or move action according to the code below:
**
**      Bit:      7 6 5 4 3 2 1 0
**            p x x x y y y y
**
**      p:      Plot flag. If set, "draw to" new point, else "move to" it.
**      xxx:      3-bit unsigned integer  (0...7). X coordinate of new point.
**      yyyy:      4-bit unsigned integer (0..15). Y coordinate of new point.
**
** The baseline is y = 4 instead of y = 0, so characters with parts
** below it can be drawn properly without a need for sign bits.
** Function "code_to_ucoord()" transforms these coordinates into
** actual user coordinates.
**
** Example:      code for character 'L': "\032\224\324" translates to:
**            moveto(1,10); drawto(1,4); drawto(5,4);
``````

Function:

``````static void
code_to_ucoord (char c, HPGL_Pt *pp)
/**
** Converts internal one-byte code (in c) for a character vector
** into HP-GL coordinates (pointed to by pp)
**/
{
double      x,y;

/*
* RS6000 bug fix:
*       outer braces of casts removed, costing 2 double ops
* My guess: "char" is unsigned on RS6000
*/
x = (double) (c >> 4)   - 1.0;      /* Bits 4,5,6 --> value 0..7 */
y = (double) (c & 0x0f) - 4.0;      /* Bits 0-3   --> value 0..f */
[color=#ff0000]
// NOTE: the stuff below is not important to my question[/color]
pp->x = tp->Txx * x + tp->Txy * y + tp->refpoint.x + tp->offset.x;
pp->y = tp->Tyx * x + tp->Tyy * y + tp->refpoint.y + tp->offset.y;
}
``````
``````code_to_ucoord (char c, HPGL_Pt *pp)
``````

Given that a 'char' can only hold a value between -128 thru 127 inclusive how are you passing it the value 324?

Yeah - I just caught that too. Digging through the code I found that when the function is called the arg is ANDed with 127.

code_to_ucoord ((char)(*ptr&0x7f), &p);

I loaded this all into a sketch but still getting weird values.

``````void setup() {
Serial.begin(115200);
}

void loop() {
// ** Example:      code for character 'L': "\032\224\324" translates to:
// ** moveto(1,10); drawto(1,4); drawto(5,4);

code_to_ucoord(032);
delay(1000);

code_to_ucoord(224);
delay(1000);

code_to_ucoord(324);
delay(1000);
}

void code_to_ucoord (char z)
/**
** Converts internal one-byte code (in c) for a character vector
** into HP-GL coordinates (pointed to by pp)
**/
{
double x,y;

char c = z  &0x7f;
x = (double) (c >> 4)   - 1.0;       /* Bits 4,5,6 --> value 0..7 */
y = (double) (c & 0x0f) - 4.0;       /* Bits 0-3   --> value 0..f */

Serial.print("c ");
Serial.println(c, DEC);

Serial.print("x ");
Serial.println(x);

Serial.print("y ");
Serial.println(y);
//  pp->x = tp->Txx * x + tp->Txy * y + tp->refpoint.x + tp->offset.x;
//  pp->y = tp->Tyx * x + tp->Tyy * y + tp->refpoint.y + tp->offset.y;
}
``````

I see nothings changed:

code_to_ucoord(032); ← OCTAL VALUE
code_to_ucoord(224); ← OUT OF RANGE, ‘char’ -128 thru 127
code_to_ucoord(324); ← OUT OF RANGE, ‘char’ -128 thru 127