Shop OBEX P1 Docs P2 Docs Learn Events
random value within range -SOLVED- — Parallax Forums

random value within range -SOLVED-

Roger LeeRoger Lee Posts: 339
edited 2009-06-04 17:33 in Propeller 1
I can use random operator (?) to generate value from 0 to 63 ( or any power of 2).
I can then add one to get 1 to 64 range.

How do I make the range 1 to 9 , for example?

Post Edited (Roger Lee) : 4/13/2009 9:28:54 PM GMT

Comments

  • SRLMSRLM Posts: 5,045
    edited 2009-04-13 05:16
    Modulus is the traditional computer science answer. Something like:

    small_number = (random % 8) + 1

    There are eight different numbers, starting at 1.
  • mparkmpark Posts: 1,305
    edited 2009-04-13 08:07
    Just remember that in Spin, the modulus operator is //.

    Also, the ? operator produces 32-bit results, which Spin will interpret as positive and negative numbers. Using // on a negative number won't do what you want, so mask off the sign bit first, as in

    small_number := (?random & $7fff_ffff) // 9 + 1 ' range 1..9

    Note that simply using the mod operator can, depending on the modulus, result in a very slightly non-uniform distribution. Probably not enough to make any practical difference, but something you should at least be aware of.
  • virtuPICvirtuPIC Posts: 193
    edited 2009-04-13 08:18
    Uh-oh! Isn't the SPIN PRNG a LFSR? Ahem, in whole words: ...the pseudo random generator a linear feedback shift register? In this case you have to remember a few points:
    • LFSR are not cryptographically usable. They are easily crackable.
    • LFSR give good noise for Monte Carlo simulation.
    • LFSR give white noise.
    • LFSR PRNGs don't produce 0. A 32 it LFSR would produce numbers in [noparse][[/noparse]1, 232-1]

    Everything else written so far is correct.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Airspace V - international hangar flying!
    www.airspace-v.com/ggadgets for tools & toys
  • Roger LeeRoger Lee Posts: 339
    edited 2009-04-13 21:24
    Thanks for the help, all I needed was the word "MODULUS".

    Works like a charm.

    Roger
  • ericballericball Posts: 774
    edited 2009-06-04 15:42
    Instead of using modulus, you can use multiply:
      output := ||(random? ** (input << 1) ) + 1
    
    



    SPIN's LSFR produces numbers in the range of -2^31 through 2^31-1, or a 32 bit signed number. Now, instead of thinking of this as a positive integer, think of it as the fractional component of a fixed point number. If we ignore that it's signed for the moment, random? / 2^32 = 0 through 1-2^-32. If you multiply this by your input you get 0 through input - 1. SPIN's high multiply (**) operator does exactly that : x = a * b / 2^32. So the only problem we are left with is random? being a signed value which yeilds random? ** input = -input/2+1 through input/2-1. So multiply input by 2 (via a shift) before the high multiply, then take the absolute value to get 0 through input-1. Add one to the result to get 1 through input.

    This method should be faster than modulus (asuming the multiply is faster than division and the other operations are trivial).

    @virtuPIC - a standard LFSR will have a null somewhere in it's number space. It doesn't have to be zero (although it commonly is), it may be -1 (all bits set) or any other value (though all clear or all set are most common unless there's a specific requirement). A bad LFSR will get trapped if it is seeded with the null while A good LFSR will escape the null, never to return. LFSRs also don't have to be 2^n-1 sequences. The Atari 2600 used some interesting LFSRs as pixel counters.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Composite NTSC sprite driver: http://forums.parallax.com/showthread.php?p=800114
    NTSC color bars (template): http://forums.parallax.com/showthread.php?p=803904
  • mparkmpark Posts: 1,305
    edited 2009-06-04 17:33
    Also see PhiPi's elegant solution here:
    http://forums.parallax.com/showthread.php?p=802420
Sign In or Register to comment.