Pages: [1]   Go Down
Author Topic: help with bit shifting?  (Read 428 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 296
Got Karma?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
 
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:
** 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:
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;
}
Logged

Des Moines, WA - USA
Offline Offline
God Member
*****
Karma: 25
Posts: 779
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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?
« Last Edit: December 18, 2010, 06:51:24 pm by lloyddean » Logged

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 296
Got Karma?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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


Logged

Des Moines, WA - USA
Offline Offline
God Member
*****
Karma: 25
Posts: 779
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Pages: [1]   Go Up
Jump to: