Log In  


a=100
m1="-2"+0
m2=-2
print(m1) --- prints -2
print(a*m1) --- prints -199.998
print(a*m2) --- prints -200

While m1 prints as -2, a*m1 seems to be -199.998. Multiplying by m2, the exact same number but not parsed from string, doesn't have this problem and gives the correct answer: -200.

Maybe it's some sort of an off-by-one problem in the parsing that "-2"+0 implicitly does?

Anyway, would be great if this could be fixed for 0.1.9 :).

1


PICO-8 is entirely capable of holding -2.0 in a variable perfectly. I'm guessing it's a bug in the atof()-style parser...

Yeah, I just did the same test with a routine I use to print the exact contents of lua values in hex. Here's the result:

Definitely a bug. Good find.


It's also interesting that this erroneous 0xfffe.0001 still prints as "-2". I suppose this is also a bug, since numbers with different internal representations print the same, and only side effects can show you they're different - unless there is some internal max precision when printing?


I'm pretty sure it's set to show, like, 3 or 4 decimal digits, max. With 16-bit fractional precision, I suspect a lot of fractional numbers aren't quite what they get rounded off to when displayed. When you ask for 1.3, I'm betting that can't actually be encoded perfectly, but the rounding off in the print function saves you some headaches. Most of the time that's probably a good thing.


True, if you're not able to influence the precision manually with a format string or somesuch, dropping after 3 decimals seems like a sane idea. That part is a non-issue then.


Honestly, I'd rather there be enough precision to show the minimum fractional value, for ease of diagnosing exactly this kind of problem. I've run into similar before (as a bug in my own code, not in PICO-8).


Do numbers in Pico-8 have some kind of special format? Is it just a standard 16-bit floating point number with 4 digits of accuracy, or something else?


@Danjen: They're signed 16.16 fixed point, range: [-32768.0, 32767.99999] or [0x8000.0000, 0x7fff.ffff]


Try this one:

> a="-1"
> a=a+0
> print(a)
-1
> if a==-1 then print(12) end  -- no output
> if a=="-1" then print (12) end  -- no output

-- if the above is not enough
> b=5+a
> print(b)
4
> if b==4 then print(12) end  -- no output
> if b=="4" then print (12) end  -- no output

Aaaaaack! I wasted about 8 hours narrowing this down trying to figure out why my animations wouldn't run the same with data parsed from a string instead of hard coded. Next, I get to figure out what the heck to do about it.


The workaround appears to be:

> a="-1"
> a=flr(a)

Be careful with flr() and negative decimals. That might make a==-2

edit: though I assume that was probably the goal in this case


Yeah, I'm well aware of rounding behaviors with negatives. It appears all negative conversions come in .0000262 too high. Thus, flr() works so far for both positive and negative to-number conversion.

I more want to know when and if this ever will be fixed. This is a pretty painful flaw in the language and greatly adds to my dislike of P8 Lua.


I put in a bug report on this long ago...

It doesn't always get it wrong:

I think it only messes up when the conversion is exact.

Something like this might be a good workaround:

function stofp(s)
 if sub(s,1,1)=="-" then
  return -(sub(s,2,#s)+0)
 else
  return s+0
 end
end

Thanks, I adapted it a little for my project:

function string_tonum(val)
  if sub(val, 1, 1) == '-' then
    return - tonum(sub(val, 2))
  else
    return tonum(val)
  end
end

(sub(s, n) will get the substring from n to the last character, so there is no need to pass #s)


Fixed in 0.1.12?

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

API Changes

API changes that required a cart version bump:

  • divide and abs sign flipping for 0x8000.0000
  • sqrt(0x0000.0001) freezes
  • "-1"+0 evaluates to 0xffff.0001


[Please log in to post a comment]