signed difference between two bytes
ManAtWork
Posts: 2,176
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
In SPIN, my first idea was
So is
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 ~> 24the best way to go or does somebody know a more elegant method?
Comments
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:
If the byte values are not signed (i.e. $ff = 255), then this is the correct expression, as Mike pointed out:
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
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
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
calculate initial difference (A -
Loop:
read in counter and expand MSB ( A and
substract from new value latched value to get the difference (A and
latch new value (A and
integrate the differences
PS: what about the servo controller? (see PM)