Log In  


Cart #evalbug-0 | 2020-11-06 | Code ▽ | Embed ▽ | No License
2

Hi @zep,

Unless I'm missing something obvious, I seem to have stumbled on a weird bug.

It seems that inside an FOR..LOOP (potentially other places too),
if the incrementor is something other than 1 or 0.5 (such as 0.4),
then even though PRINT is "saying" the value is 1.4, it is not comparable with that value
(perhaps a precision/rounding happening in PRINT?)

Code below:

cls()

?"-- works -----"
for z=0,3,.5 do
	print(z)
	if(z==1.5) print("😐")
end

?"-- fails -----"
for z=0,3,.4 do
	print(z)
	if(z==1.6) print("😐")  --<<<< NEVER hits this 
end

Hope this helps (or someone can point out the error of my ways!)

Thx

2


4

It's because PICO-8 internally stores numbers in a 32-bit 16.16 fixed-point format. This is why using tostr(v,true) to get the hex version gives you 4-hex-digits-DOT-4-hex-digits ("0x????.????"). All fractional portions are rounded off to the nearest 1/65536th.

You can use 0.5 without problems because PICO-8 can store 0.5 perfectly as 32768/65536. However, it can't store 0.4 perfectly, it can only use the approximation 26214/65536, which is actually 0.399993896484375.

The print() function, or more specifically the tostr() function it calls to format numbers, rounds off after the fourth decimal place. If you print(0.4), you'll get "0.4", because it rounds up that 9 in the fourth decimal place.

Calculate how many steps you'll need and iterate that many times, rather that iterating by the step length and seeing how far you've gone.

(This happens even with 64-bit floats on real processors, by the way. It's not specific to PICO-8.)


1

Thanks for the detailed explanation @Felice,
figured it was something like this.
I've already gone with an alternative approach (similar to ur suggestion), but good to know the "why". 🤓



[Please log in to post a comment]