Log In  


Hi Zep, or whoever is reading this!

I'm playing around with Pico-8 and found a few things with the numbers that I wasn't expecting.

The lowest number in pico-8 is: 0x8000.0000 or -32768.
The highest number in pico-8 is 0x7FFF.FFFF or 32767.999 or about 32768

Keeping that in mind, doing this:

printh(abs(0x8000.0000) == 0x8000.0000)

will print out true, the same number! Which is a negative number (-32768). I wouldn't think that abs should ever give you a negative number. I would expect the above code to print out 0x7fff.ffff!

And the other really weird thing is that these are all true statements:

printh(1/0x0000.0000 == 0x7fff.ffff) -- understandable, this is in the manual.
printh(1/0x0000.0001 == 0x0000.0000) -- huh? i would expect this to be 0x7fff.ffff also
printh(1/0x0000.0002 == 0x8000.0000) -- now it is a negative number!!! this should also be 0x7fff.ffff
printh(1/0x0000.0003 == 0x5555.5555) -- these two are fine and make sense. :)
printh(1/0x0000.0004 == 0x4000.0000)
printh(1/0x7fff.ffff == 0x0000.0002) -- and this one actually makes sense too. though of course it isn't transitive or whatever.

I found these while porting a raytracing program to Pico-8 and breaking it apart to understand it. I'm running Pico-8 on Linux. And running version 0.1.11g.

2


Note that limits are actually [-32768,32767]
And yeah, you'll have to live with nasty overflow & wrap around numbers.

Hint: don't get ever close to these limits :_[
(or roll your own "float" number - lua makes it "relatively" easy to do)


I guess I was thinking the built in functions should be able to handle the overflow. Who knows, maybe they shouldn't. On one side it could be a hardware constraint for the fantasy console and feeling like you're programming at a lower level.

But on the other side the divide by zero is handled/documented so why isn't the divide by 0x0000.0001 talked about/documented?

And should the absolute value of -32768 be -32768? Maybe someone has already brought this up before. I would be interested in explanations if it has already been talked about though.


I think I've found a related bug:

a = 0x8000
b = a+1
c = b+1

print("a="..a)
print("b="..b)
print("c="..c)

print("")
print("counting from a to b:")
for i=a,b do
	print(i)
end

print("")
print("counting from b to c:")
for i=b,c do
	print(i)
end

should first count from -32768 to -32767, then from -32767 to -32766 ... but it doesn't:

I think the for loop is treating -32768 as +32768, too.


1

0x8000 is a special number, like 0x0000. Both are technically without sign, but get assigned to negative and positive in 2's complement mode just for the sake of simplicity & balance.

Just like -0x0000 == 0x0000, -0x8000 == 0x8000.

(Some people supposedly call it "the weird number", but I call it "the outpost", since it's the farthest number from the origin in 2's complement, in both directions.)

In short, it's not a bug that they can't be negated to get a different number.

HOWEVER

It DOES seem to be a bug that you can't do a for loop that involves -32768 as an endpoint. That should probably be fixed.


1

Yeah, and this is a bit tricky to fix. The reason is that the Lua virtual machine internally starts its “for” loops at “start - step” instead of “start” for performance reasons. Since -32768 minus 1 is +32767 which is greater than the “end” value, the VM thinks the loop is finished.

This also happens whenever “start - loop” underflows, so the following loop will not work either, even though all parameters are well within the number system limits:

for i = -30000, 30000, 10000 do print(i) end


[Please log in to post a comment]