How do you deal with range overflow? The numbers beyond 32767 warp to -32766 in pico8's 16 bit signed system when calculating. This is sometimes enough, but not always. For example,

function distance(x1,y1,x2,y2) return sqrt((x2-x1)^2+(y2-y1)^2) end |

will sometimes (very often actually) return 0 as a result of taking sqrt of the negative wrapped number. This is occasionally crutial. Is there a workaround to compute this as if this was an unsigned system?

I'm not sure if this gives you the results you want, @collinthenewmaker.

You use `,2`

in `tonum()`

and `tostr()`

to swap between a large integer saved as a string and back again to a real number that limits to -32768.9999 and 32767.9999.

function distance(x1,y1,x2,y2) return tostr(sqrt(tonum(x2,2)-tonum(x1,2))^2+(tonum(y2,2)-tonum(y1,2)^2),2) end x1="0" y1="0" x2="100000" y2="50000" cls() ?distance(x1,y1,x2,y2) |

I make use of this HERE:

You can use an approximation formula to avoid squaring and rooting the values.

Previous PICO-8 discussion: https://www.lexaloffle.com/bbs/?tid=36059

P.S. The 32-bit encoding suggestion does not work as written because the squaring operation will take the exponent into account, then round. E.g. `tonum("500",2)^2 == 0`

The 32-bit encoding trick does work with an approximation formula, which merely scales by a positive constant then adds:

function approx_dist(dx,dy) local maskx,masky=dx>>31,dy>>31 local a0,b0=(dx+maskx)^^maskx,(dy+masky)^^masky if a0>b0 then return a0*0.9609+b0*0.3984 end return b0*0.9609+a0*0.3984 end ?tostr(approx_dist(tonum("100000",2),tonum("50000",2)),2) |

prints 116008. In a higher precision floating point environment, I get approximately 111803.

My naive idea is this: Do numbers immediately wrap after performing math at them (32767+1=-32766) or do they wrap after you assign them to variables or return them (a= 32768, a=-32766)? If the latter, can the system compare the big numbers? If yes, i think you can do the sqrt(pythagorean stuff here) - 32766 to get a number in the 16bit range with it's 0 shifted to -32766, somehow emulating the unsigned system. you can then add 32766 back for comparing (if dist+32766<2 then ...).

Edit: You could actually not add 32766 and just use (if dist < 2-32766)

@colinthenewmaker.

I'm afraid that numbers wrap in memory as soon as the calculation occurs.

There was this post a few weeks ago which gives a distance formula without needing to square or sqrt the numbers: https://www.lexaloffle.com/bbs/?tid=49827

Overflow will still happen for large enough numbers but it'll take a lot longer. It quite happily calculates the distance between (0, 0) and (16384, 16384) as 23170.5, for instance.

[Please log in to post a comment]