Log In  


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.

1


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]