Shop OBEX P1 Docs P2 Docs Learn Events
C to Spin Conversion issue — Parallax Forums

C to Spin Conversion issue

Greg LaPollaGreg LaPolla Posts: 323
edited 2021-07-11 17:42 in Propeller 2

P is a pointer to a variable of type long (int32_t in c)

Sensor reading at idle puts out readings between 2_300 - 2_500

after a few iterations this routine is returning values above 100_000

I have tried using x.long and x.word but that doesn't seem to help at all.

In the C version they typecast x as long but in this case its already a long in the spin2 version

Here is the original C Code

//  Average DC Estimator
static int16_t averageDCEstimator(int32_t *p, uint16_t x)
{
    *p += ((((long) x << 15) - *p) >> 4);
    return (*p >> 15);
}

Here is the spin2 code

PUB averageDCEstimator(p, x): result

  long[p] += (((x << 15) - long[p]) >> 4)
  result := (long[p] >> 15)
  return result

Comments

  • RaymanRayman Posts: 14,744

    Maybe that right shift of 4 needs to be an arithmetic shift in Spin?

  • pik33pik33 Posts: 2,387
    edited 2021-07-11 19:05

    I don't know what C does with pointers as I program mainly in Pascal - Pascal does pointer arithmetic such as if you add 1 to the pointer, it points to the next long.
    In Spin you have to add 4 to the "pointer" to point to the next long

  • @Rayman said:
    Maybe that right shift of 4 needs to be an arithmetic shift in Spin?

    I would assume that would equate to a divide by 16 ?

  • @"Greg LaPolla" said:

    @Rayman said:
    Maybe that right shift of 4 needs to be an arithmetic shift in Spin?

    I would assume that would equate to a divide by 16 ?

    Kindof, but arithmetic right shift and signed division have different rounding behavior for negative numbers.

  • In Spin 1 the arithmetic right shift operator is "~>". Hopefully Spin 2 has the same operator.

  • AribaAriba Posts: 2,690

    @"Dave Hein" said:
    In Spin 1 the arithmetic right shift operator is "~>". Hopefully Spin 2 has the same operator.

    No, that would be too easy ;)
    The operator is now: SAR

    Andy

  • RaymanRayman Posts: 14,744

    Wonder if it would be better to have the default shift in Spin2 be arithmetic...
    Being as the usual variables are signed...

    Looks like C automatically decides for you which shift to use.

  • Right shifts in C depends on the sign attribute of the value that is being shifted. A signed value uses a signed shift, and an unsigned value uses an unsigned shift. In Spin, the type of shift is based entirely on the operator that is used. I suppose the ">>" operator could have been defined as a signed shift, but Chips chose to make it unsigned.

  • So divide by 16 works as well as SAR 4.

    Thanks for the input

  • Dave HeinDave Hein Posts: 6,347
    edited 2021-07-12 16:11

    They both do similar things, but you will get slightly different results for negative numbers. (-1 SAR 4) will be -1, and (-1/16) will be zero. Also, a divide requires more cycles than a shift.

    It would be more accurate to round by adding half of the shift amount before shifting down, but then you'll get different results than the Spin code produces. So for a shift of 4 you would first add 2^3 = 8, and for a shift of 15 you would add 2^14 = 16384. However, if the Spin code works fine without rounding I wouldn't bother with rounding in the C code.

  • @"Greg LaPolla" said:
    So divide by 16 works as well as SAR 4.

    Thanks for the input

    No, divide by 16 is the same as SAR 4 only for positive numbers. For negative numbers they are different. Use SAR 4, it's much faster than divide anyway.

Sign In or Register to comment.