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 :).
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.
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]