Go Down

Topic: help with bit shifting? (Read 494 times) previous topic - next topic

roypardi

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:

Code: [Select]
 
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:

Code: [Select]

** 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:
Code: [Select]

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

lloyddean

#1
Dec 19, 2010, 12:49 am Last Edit: Dec 19, 2010, 12:51 am by lloyddean Reason: 1
Code: [Select]

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?

roypardi

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.

Code: [Select]

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



lloyddean

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

Go Up