Go Down

Topic: help with bit shifting? (Read 590 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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy