Sorry, I was wrong, you need +1 and another cast to avoid truncation:

#define RandInt(n)  (((UInt32) SysRandom(0) * (n)) / ((UInt32) sysRandomMax
+ 1))


-----Original Message-----
From: Michael Glickman [mailto:[EMAIL PROTECTED]]
Sent: Wednesday, 21 November 2001 2:53 PM
To: Palm Developer Forum
Subject: RE: get a random number within a specified range


Hello

Just a minor observation.

In case of PalmOS you can probably avoid using doubles,
because the random value is Int16 and is really even a 15-bit integer.

Therefore you can have (assuming n > 0)

#define RandInt(n)  (((UInt32) SysRandom(0) * (n)) / sysRandomMax)

If (and only if!) the range is a power of 2 and less
than 32K you can happily use a more efficient

#define RandInt1(n)  (SysRandom(0) & (n-1))

which is efectively the remainder.

Michael

  

-----Original Message-----
From: Danny Epstein [mailto:[EMAIL PROTECTED]]
Sent: Wednesday, 21 November 2001 1:33 PM
To: Palm Developer Forum
Subject: RE: get a random number within a specified range


> unsigned long RandomNum(unsigned long n)

SysRandom only returns 15 bits of random data, so using a 32-bit argument
for the desired range is potentially confusing. If you pass in a large value
for n, you'll get large results, but some of the values between zero and n-1
will never be returned. OTOH, the way you're using n within the function
would require a cast if it was declared as a 16-bit argument.

> {
>  static Boolean initialized = false;
> 
>  unsigned long x;
>  if (initialized == false) {
>   initialized = true;
>   SysRandom(TimGetTicks());
>  }
>  if (n == 0)
>   n = 1;
> 
>  x = SysRandom(0) ;

Storing a 16-bit (15, actually) in a 32-bit variable. So far so good...

>  x = (double)  x / ( (double) (1 + sysRandomMax / n )) ;

Why are you using doubles? What I mean is why are you using floating point?
The "sysRandomMax / n" expression will round down. I'm not sure if I
understand this statement. AFAICT, what you're trying to do, mathematically
speaking, is:

        SysRandom(0) * n / sysRandomMax

If you limit n to be in the [0..32767] range, then you can do this using
32-bit integer math:

        x = x * n / sysRandomMax;

Note that this doesn't mind n being zero. Many people use:

        SysRandom(0) % n;

despite the fact that it isn't uniform, particularly for large n. If n is a
power of two, you can use masking, for example:

        SysRandom(0) & 0x001F;

returns a random number in the [0..31] range.

> 
>  return x;
> }

-- 
For information on using the Palm Developer Forums, or to unsubscribe,
please see http://www.palmos.com/dev/tech/support/forums/

-- 
For information on using the Palm Developer Forums, or to unsubscribe,
please see http://www.palmos.com/dev/tech/support/forums/

-- 
For information on using the Palm Developer Forums, or to unsubscribe, please see 
http://www.palmos.com/dev/tech/support/forums/

Reply via email to