Go Down

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

#### roypardi

##### Dec 19, 2010, 12:39 am
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 voidcode_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 amLast 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

#2
##### Dec 19, 2010, 01:04 am
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

#3
##### Dec 19, 2010, 01:12 am
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