Shop OBEX P1 Docs P2 Docs Learn Events
signed difference between two bytes — Parallax Forums

signed difference between two bytes

ManAtWorkManAtWork Posts: 2,176
edited 2012-11-20 01:10 in Propeller 1
Assume we have two hardware counters a and b (like encoders, timers, event counters or whatever). It is often necessary to compare them to see which one is "higher" and by how much. Unfortunatelly, if they are byte or word signed we cannot simply write a-b because they wrap around and $FF is actually one below $00, for example. In PASM we could do something like
    sub a,b
    shl a,#24
    sar a,#24

In SPIN, my first idea was
    ~(a - b)
But sign-extend (~) doesn't work for expressions in brackets but only for (byte sized) variables driectly.
    (~a - ~b)
doesn't work, obviously. $7F - $80 would erronously return 255 instead of -1.

So is
    (a - b) << 24 ~> 24
the best way to go or does somebody know a more elegant method?

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2012-11-19 06:44
    Your last solution (using << and ~>) is the best. It uses only two operations, just like the PASM solution.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-11-19 07:52
    ManAtWork wrote:
    Unfortunatelly, if they are byte or word signed ...
    ManAtWork wrote:
    ... $7F - $80 would erronously return 255 instead of -1.

    Those two statements are inconsistent with each other. On the one hand, you seem to want to treat the byte values as signed. On the other hand, you don't like the results when they're treated that way. You will have to make up your mind, first, which it is that you want. If you want to treat the byte values as signed (i.e. $ff = -1), the correct epxression is:
    ~a - ~b

    If the byte values are not signed (i.e. $ff = 255), then this is the correct expression, as Mike pointed out:
    (a - b) << 24 ~> 24

    Since you mentioned encoders, I have the feeling that what you're grasping for is a modular comparison, such that if a is ahead of b by 128 or more, it should actually be considered to be behind. The second expression will give you that.

    -Phil
  • ManAtWorkManAtWork Posts: 2,176
    edited 2012-11-19 08:15
    You will have to make up your mind, first, which it is that you want.

    My mind is not the problem. ;-) I just haven't explained clearly enough. Of course, the byte counters are neither signed nor unsigned. They are just a "window" of least significant bits out ouf a bigger, (unaccessible) external value. Therefore they are frequently overflowing and should be treated as modulo arithmetic. And yes, of course, you can't tell wether one counter is leading the other by 1 or by 257 or following by -255. You have to assert by design that the following error is no more than +/-127, for the example of encoders.

    So actually modulo counters and a signed result is what I want and (a - b) << 24 ~> 24 is the correct solution.

    Thanks Mike and Phil
  • ErNaErNa Posts: 1,752
    edited 2012-11-20 01:10
    As I understand:
    there are two counters which can overrun and the aim is to find out which counter counts more. There is no way to figure this out if the initial position is not known and if the counters can count more than half range between two readouts,
    This said the assumption is: the counters start at an initial value less than 1/2 range and the counters are read frequently enough.

    I would solve this task that way:
    Read in the initial counter values and expand MSB. Latch values (A and B)
    calculate initial difference (A - B)

    Loop:
    read in counter and expand MSB ( A and B)
    substract from new value latched value to get the difference (A and B)
    latch new value (A and B)
    integrate the differences
    ALatch = ~CntA
    BLatch = ~CntB
    Diff = ALatch - BLatch
    
    repeat
       ADiff   =   ~CntA - ALatch
       ALatch +=   ADiff
       BDiff   =   ~CntB - BLatch
       BLatch +=   BDiff
       Diff   +=   ADiff + BDiff
    
    
    

    PS: what about the servo controller? (see PM)
Sign In or Register to comment.