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
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
Stuck in a line using tostr() to get the raw hexadecimal:
...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.
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.
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
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.
> 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.
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
[Please log in to post a comment]