Log In  

can someone tell me how to fix this bug?

function range(low,high,step)
    local t={}
    for i=low,high,step do
        add(t,flr(i/step)*step)--
    end
    return t
end

for example I am doing this for my menus..

function run_menu1()
    scene.upd = upd_menu1
    scene.drw = drw_menu1

    --options selectors
    optiony=1 --optiony
    options=
    {
                --optionx and options
        {1, {false , true       }}, --powerups
        {1, {"grow", "infinite" }}, --tail type
        {42,range(-4.0, 4.0, 0.1)}, --player speed
        {42,range(-4.0, 4.0, 0.1)}, --player accel on any deaths
        {1, range( 0.0,32.0, 1.0)}, --border size
        {42,range(-4.0, 4.0, 0.1)}, --border speed
        {42,range(-4.0, 4.0, 0.1)} -- border accel on any deaths
    }
end
P#73327 2020-02-21 23:19 ( Edited 2020-02-21 23:20)

You can't really, because 0.1 is not an exact number in PICO-8. A quick fix would be to use 0.125 or 0.0625 as the step valie instead.

P#73330 2020-02-22 01:17

Alternately you could store the value times ten, then divide it when using or displaying it.

P#73338 2020-02-22 10:04

@Shadowblitz16

With apologies to Sam, I have to differ with one of his two points.

It's true that you're fighting against binary representation of decimal 0.1. Binary, no matter how many bits, no matter whether it's PICO-8 16.16 fixed-point or full-fat 64-bit floating-point, can't truly represent 0.1, just like you can't truly represent 1/3 in decimal, no matter how far out you write your 0.333333⋯ value. Instead, you're getting a value slightly less than 0.1, which when added up 10 times doesn't quite equal 1.0. See here:

However, your code can still be made to work! The issue is just that it wasn't written with that information in your head yet.

This tweaked version will work for you, mainly because it (A) assumes you've given it a range that's at least close to being divisible by the step value, so it can (B) work around the reduced precision on PICO-8:

-- heavily-commented version
function range(low,high,step)
  -- how long is the range?
  local len=high-low
  -- presumably the caller gave us a range divisible by the step,
  -- but let's be careful and round off.
  local steps=flr(len/step+0.5)
  -- get our steps in
  local t={}
  for i=0,steps do
    -- at the ith step, we've covered i/steps of the length.
    -- note we arrange the math so we multiply *before* dividing, 
    -- to preserve precision as long as possible.
    -- division is where you can lose bits to rounding.
    -- beware of multiplication overflow >32767 though.
    add(t,low+len*i/steps)
  end
  return t
end

-- same, but just the code
function range(low,high,step)
  local len=high-low
  local steps=flr(len/step+0.5)
  local t={}
  for i=0,steps do
    add(t,low+len*i/steps)
  end
  return t
end

You could also just give it a range and tell it how many steps you want across the range, rather than implying it by the step size:

function range(low,high,steps)
  local len=high-low
  local t={}
  for i=0,steps do
    add(t,low+len*i/steps)
  end
  return t
end

That way you don't have to worry about fractional bits and precision and rounding off and such.

In your case, though, the first function should just drop in and work pretty much as expected.

P#73336 2020-02-22 10:43

thankyou guys I was wondering about this since it works in languages like C#.

@Felice does this work with any number?

P#73353 2020-02-22 19:40

@Shadowblitz16 If you do it enough, you'll find it doesn't work in C# either, it just takes a lot more iterations for the error to add up in a 32 or 64 bit floating point number than it does in a 16.16 fixed point number.

P#73358 2020-02-22 22:46

@Felice I tried doing it with even lower numbers but it doesn't seem to work.

    options=
    {
     {2, range( 01.00,04.00,01.00)}, --players
        {1, {false      , true      }}, --powers
        {1, {"static"   ,"grow"     }}, --plrtype
        {1, range( 00.00,32.00,01.00)}, --plrsize
        {1, range( 00.10,01.00,00.01)}, --plrstep
        {5, range(-00.25,00.25,00.01)}, --plrgain
        {1, {"static"   ,"grow"     }}, --maptype
        {1, range( 00.00,32.00,01.00)}, --mapsize
        {1, range( 00.10,01.00,00.01)}, --mapstep
        {5, range(-00.25,00.25,00.01)}  --mapgain
    }

@sparr ahh ok I though C# handled such floating errors

P#73400 2020-02-24 02:50 ( Edited 2020-02-24 02:52)

@Shadowblitz16

What's not working? I tried those ranges with the function I gave you and they all seemed to work fine.

P#73407 2020-02-24 09:46 ( Edited 2020-02-24 09:46)

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-04-18 23:09:53 | 0.031s | Q:22