Bit twiddling in spin
mhm21
Posts: 14
I would like to pare down the following if-else statement for rounding using some clever logical operations. I realize that shifting would solve a large portion of this problem, but my time step is fixed at "10". I feel comfortable doing this in assembly with flags and such, but this application requires spin...
I feel stupid for asking this, but I'm lost!
if A < 0 B += (A - 5)/10 else B += (A + 5)/10
I feel stupid for asking this, but I'm lost!
Comments
B += (A + 5 + 10 * (A ~> 31)) / 10
EDIT: but, looking at that, the 10 / 10 can be reduced...looks like it might work? (no prop here to test)
B += (A + 5) / 10 + (A ~> 31)
Jonathan
B += (A + (5 <# A #> -5)) / 10
The only cases where the limits are not -5 or 5 are when you wouldn't round up anyway. [8^)
Jonathan
Lawson
This is my new equation below:
B+=(A+((A<0)|1*5))/10
Y := (X + X // 10) / 10
in general to round off a number when dividing by factor N:
Y := (X + X // N) / N
This works because the // operator in Spin in is symmetric around zero, X//N = -(-X//N), e.g., -14//10 = -4 and 14//10 = 4.
quick demo attached.
This is a great example of a speed / size tradeoff. The // version is 3 bytes smaller and 160 clocks slower than the limit version. If doing this in PASM I would definitely go the limit route, since the // operation is expensive whereas the limit operation is native PASM. If doing this in Spin I would use the // version, especially when 'N' is not a constant.
Jonathan
.