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?

P#120638 2022-11-13 22:09

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:

https://www.lexaloffle.com/bbs/?pid=101378

P#120640 2022-11-13 22:20 ( Edited 2022-11-14 06:48)

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#120641 2022-11-13 22:46

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.

P#120643 2022-11-13 23:14

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)

P#120656 2022-11-14 03:39 ( Edited 2022-11-14 04:31)
1

Here's something I came up with that combats the overflow issue while still using the original sqrt function

 ```function distance(x1,y1,x2,y2) return sqrt(((x2-x1)/256)^2+((y2-y1)/256)^2)*256 end```
P#120671 2022-11-14 06:58

@colinthenewmaker.

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

P#120685 2022-11-14 10:24
1

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.

P#120686 2022-11-14 10:47