Shop OBEX P1 Docs P2 Docs Learn Events
RealRandom number between 0 and x — Parallax Forums

RealRandom number between 0 and x

Robot FreakRobot Freak Posts: 168
edited 2008-10-29 21:47 in Propeller 1
The RealRandom object is great, but it doesn't give random numbers between 0 and x (to be specified).

This doesn't work:
repeat x
  random += rr.random & 1


Because it gives numbers that are always near x/2.

This doesn't work:
x /= 2
repeat while x <> 0
  temp := rr.random & 1
  if(temp == 1)
    random += x
  x /= 2


Because of the divisions the random numbers don't reach x.

Any idea's how to get this working?

Kind regards,
Robot Freak

Post Edited (Robot Freak) : 10/28/2008 4:28:23 PM GMT

Comments

  • LeonLeon Posts: 7,620
    edited 2008-10-28 16:47
    Convert it to a real number between 0 and 1 by dividing it by 2^32, then multiply by x and take the integer part.

    Leon

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Amateur radio callsign: G1HSM
    Suzuki SV1000S motorcycle
  • Robot FreakRobot Freak Posts: 168
    edited 2008-10-28 20:05
    Hi Leon,

    I tried this:
    temp := rr.random                                                          'random 32 bits
    temp := fmath.ffloat(temp)                                                 'confert to float
    temp := fmath.fdiv(temp, fmath.ffloat(%11111111111111111111111111111111))  'divide by 2^32
    temp := fmath.fmul(temp, fmath.ffloat(x))                                  'multiply by float x
    temp := fmath.fround(temp)                                                 'convert to integer
    


    Most of the times it returns zero, sometimes -649142272 or 605822208.

    So it isn't working jet, do you know what is wrong in this code?

    Thanks for your help,
    Robot Freak

    Post Edited (Robot Freak) : 10/28/2008 8:11:57 PM GMT
  • LeonLeon Posts: 7,620
    edited 2008-10-28 20:20
    I think thar RealRandom returns a signed value, you need to use an unsigned number.

    An easier way might be to use the technique used with the gcc compiler and use something like rand()%(N+1), where rand() returns a value between zero and RAND_MAX.

    Leon

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Amateur radio callsign: G1HSM
    Suzuki SV1000S motorcycle

    Post Edited (Leon) : 10/28/2008 8:31:40 PM GMT
  • Beau SchwabeBeau Schwabe Posts: 6,562
    edited 2008-10-28 21:16
    Robot Freak,
    Here is a slight modification to the "RealRandom Demo" that should do what you want...
    I added "PUB Random(N)" where N is the maximum random number minus one returned.


    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
    OBJ
      text  : "tv_text"
      rr    : "RealRandom"
      
    PUB start | i
      'start RealRandom
      rr.start
      'start terminal and show a random number
      text.start(12)
      text.str(string(10,16,11,6))
      text.dec(Random(10))
    
    PUB Random(N)
        Result := rr.random & $FFFF  ' Limit Random number to a 16-Bit value (prevent overflow)
        Result := (Result * N)/$FFFF ' Limit Random number result from 0 to N-1 
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.
  • Robot FreakRobot Freak Posts: 168
    edited 2008-10-29 13:53
    Thanks Beau!!
  • mparkmpark Posts: 1,305
    edited 2008-10-29 17:43
    Beau Schwabe (Parallax) said...
        Result := rr.random & $FFFF  ' Limit Random number to a 16-Bit value (prevent overflow)
        Result := (Result * N)/$FFFF ' Limit Random number result from 0 to N-1 
    
    

    Shouldn't that last line be
      Result := (Result * N) >> 16 ' Limit Random number result from 0 to N-1 
    
    

    Otherwise there's a 1 in 65536 chance that Result = N.
  • Beau SchwabeBeau Schwabe Posts: 6,562
    edited 2008-10-29 18:08
    mpark,

    Ohh I See.... Ok, just leave it the way it is and the number produced is between 0 and N .... NOT 0 to N-1

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.
  • mparkmpark Posts: 1,305
    edited 2008-10-29 20:50
    But if you leave it the way it is, the distribution is nonuniform: most of the time you'll get numbers from 0 to N-1, and very very rarely you'll get N, almost certainly not what is desired.
    Doing what I suggest gives a uniform distribution of the numbers from 0 to N-1 (assuming RealRandom is uniform, of course).
  • Beau SchwabeBeau Schwabe Posts: 6,562
    edited 2008-10-29 21:47
    mpark,

    idea.gif·You are correct

        Result := rr.random & $FFFF  ' Limit Random number to a 16-Bit value (prevent overflow)
        Result := (Result * N) >> 16 ' Limit Random number result from 0 to N-1 
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.
Sign In or Register to comment.