In PICO-8, the % operator causes numbers to wrap like this:
print(-1 % 10) -- 9 print(0 % 10) -- 0 print(1 % 10) -- 1 |
As I understand it, to compute x % y, you take x and add/subtract y from it, making it bigger if it's negative and smaller if it's too big, until x >= 0 and x < y. As long as y is not zero, the result should always be positive.
Well, -32768 % y is negative for some values of y:
print(-32768 % 20000) -- negative result: -12768 |
After trying a bunch of values for y, the rules look... complicated:
- If -0x4000 <= y and y <= 0x4000, then x % y is positive 32768 minus abs(y) a bunch of times, until it's in the proper range.
- If y < -0x4000 or 0x4000 > y, then x % y is -32768 plus abs(y) multiple times, but not enough times to make the number non-negative.
Is this a bug? This doesn't seem like intended (or useful) behavior to me.
Positive and negative can be quite tricky,cmounce. For instance, in a program I wrote recently I found that I was receiving a negative number for counting too high.
I wanted to make sure a number was from zero to 32767 and no higher.
For instance, try this code:
p=32760 cls() for i=1,10 do print(p) p=p+rnd()*2+1 end |
You can see the result gets "too high" and reverts to a negative number. You would think this would be the solution, but no.
p=32760 cls() for i=1,10 do print(p) p=p+rnd()*2+1 if (p>32767) p=32767 end |
But no, that doesn't work. So - how to fix this ?
Well since I only need numbers from 0 to 32767 you can do the following.
p=32760 cls() for i=1,10 do print(p) p=p+rnd()*2+1 if (p<0) p=32767 end |
Which strangely works. So, yeah, once you get up to 32767 the numbers go all wonky.
Would be nice in PICO to have a LONGINT so you can have:
-4294967296 to 4294967295
Yes, dw817, what you're saying makes sense for addition. When you go outside of PICO-8's range on the positive side, you wrap around to the negative side, because that's just how two's complement arithmetic works.
However, I'm talking about something different: I'm talking about the modulo operator, and I'm talking about an operation where the numbers never exceed the range of PICO-8's numeric type:
- -32768 is in range, per the manual: "[Numbers] range from -32768.0 to 32767.99999"
- 20000 is also in range.
- Expected value of -32768 % 20000: Add 20000 to get -12768. Add 20000 to get the final answer, 7232. At no time does a number ever exceed PICO-8's range.
- Actual value of -32768 % 20000: -12768.
You are referring to 32767 and -32768. I suspect once you reach this range a lot of functions may not work correctly around it. For when you wrap from that number to negative, likely a whole bunch of stuff stops working properly.
I think you can fix your problem with a tweak. Remember when I found Pico could not do this statement correctly ?
if (ch="(") x-=1 |
It's because the ( is on the same line.
Let's see ... a tweak I think to fix what you're doing above:
cls() a=-32768 b=20000 r=abs(a)%b*sgn(a) print(r) |
This gets the correct result.
"It's because the ( is on the same line."
I presume you bring that up to say that PICO-8 has many bugs, and we should just work around them. :-)
Yep. Almighty ZEP will eventually get around to all of 'em. Gotta admit, PICO-8 is pretty great even with its problems.
There should always be some kind of way to work around problems ...
[Please log in to post a comment]