Hi everyone, I think this can't be a bug that only I just found out so I'm posting it here for some help instead of in the bugs forum.

I seem to be having the weirdest behaviour easing out a negative var towards 0: it never becomes zero again (either negative or positive), despite printing as such. Check the below reproducer code and gif, neither y==0 nor y==-0 conditions catch the zero, even though at first you can see `true`.

Thanks!

 ```function _init() y=0 end function _update() y*=0.85 if btn(2) then y-=0.65 end end function _draw() cls() print("time: "..time()) print("y="..y) print("is y==0? "..(y==0 and 'true' or 'false')) print("is y==-0? "..(y==-0 and 'true' or 'false')) end```
P#113348 2022-06-19 11:45

2

Stuck in a line using tostr() to get the raw hexadecimal:

 ` print("y="..tostr(y,1))`

...and it looks like the way PICO-8's rounding works, 0.85 times 0xFFFF.FFFA (negative 0x0.0006) still equals 0xFFFF.FFFA, so it never gets any closer than that to 0.

I think it might be worth to stick in some close-enough check if you need the delta to reach zero.

P#113350 2022-06-19 12:38
1

Alternatively, if you want a very silly solution: it does converge from positive, so spending six tokens like:

 ` y=0.85*abs(y)*sgn(y)--sgn(y) must be the last part!`

makes the math round towards 0 both ways and reach 0.

P#113362 2022-06-19 14:00 ( Edited 2022-06-19 14:00)

Weird rounding issues, got it - makes sense now. But that "silly" solution of yours is brilliant, I just can't wrap my head around how that works?! Shouldn't `abs(y)*sgn(y)` be the same as `y`? (more rounding voodoo happening I suppose?)

P#113371 2022-06-19 15:41
1

Also, after your kind explanation I went with the following close enough solution (I'm sure there's an obvious way to optimise what I have below, my pico-8 kung-fu is not good enough):

 ```y*=0.85 if y>-0.1 and y<0.1 then y=0 end```
P#113372 2022-06-19 15:59
1

So, I think what happens is that PICO-8 rounds arithmetic down - i.e. towards negative infinity - which means for very small numbers, 0.85 times a positive y will round down and towards zero, but 0.85 times a negative y will round down and away from zero ... so by flipping the sign on negative numbers before doing arithmetic and again after, down will always be towards zero.

But I do think setting "this small number equals zero" is a better way to do it.

P#113377 2022-06-19 17:51
1

Ah got it, makes sense thanks!! Well I suppose your suggestion is the proper workaround when precision is required, whereas mine is just a shortcut for when rough is good enough. Thank you very much for everything!

P#113379 2022-06-19 18:09
1

Usually with decimal numbers like this, it can be difficult to determine the exact representation in binary, so what I usually do is implement a function to check if it is in a very small range:

 ```function near(x,y,p) p=p or 0.1 return x>=(y-p) and x<(y+p) end -- demo for i=-1,1,0.09 do print(tostr(i).." "..tostr(near(i,0))) end```
P#113399 2022-06-20 07:42 ( Edited 2022-06-20 07:42)

Alternatively you could check against the hexidecimal value, rather than the decimal digit.

In your print statements, rather than check for `y == -0` check instead for `y == 0xffff.fffa`.

If you set a variable, say "z", to -0 then check its hex value, it will be 0x0000.0000 the same as setting to 0. Probably P8 is giving you a sane version of 0, even though you asked for otherwise.

But your countdown is dealing in the raw values, so you can check against the raw values via hexadecimal equivalence.

P#113420 2022-06-20 22:50
1

> Usually with decimal numbers like this, it can be difficult to determine the
> exact representation in binary, so what I usually do is implement a function
> to check if it is in a very small range:

Thanks @MrGoober, that's a slightly saner approach actually.

@ChristopherD in this case I really want the approximate check, i.e., catching a bunch of near enough values, not an exact one - and P8 was forcing me to deal with a precise value.

P#113439 2022-06-21 10:49
1

Hi @matamouros:

Don't forget that `SGN(0)` = 1 in Pico-8 which is very non-standard with most BASIC programming languages as it is normally zero. That could also be giving you trouble.

You can fix it with a function:

 ```function mysgn(a) if (a==0) return 0 return sgn(a) end ```
P#113457 2022-06-21 23:47 ( Edited 2022-06-21 23:48)