Slightly off topic, but perhaps of some interest...


SysRandom() only returns an effective 15-bit random number.  In some cases,
you may want a random number with more "range".

I've attached the file rands.c, which contains two different random number
functions, both which are fast (the DragonBall assembly function is
blazingly fast), and they both return a 31-bit (never negative) result.
Actually both functions use the same algorithm, so they'll function the same
way (if the seed is the same).

The C version uses a global seed, and the asm version uses a pointer to a
seed passed in as an arg.  These two random number functions are based on
the widely distributed "minimum standard", so they produce good results
(nice and random), with currently no known domains.

Enjoy!
Doug.

PS: PalmDevForum doesn't allow attachments, so this is going to wrap and
look ugly! :)


---------------------rands.c---------------------
// rand31() - Return 31-bit random number (Seed is global variable).
static UInt32 rand31(void)
{
    UInt32 lo, hi;

    lo = 16807 * (Seed & 0xFFFF);
    hi = 16807 * ((UInt32)Seed >> 16);
    lo += (hi & 0x7FFF) << 16;

    if (lo > 2147483647)
    {
        lo &= 2147483647;
        ++lo;
    }

    lo += hi >> 15;

    if (lo > 2147483647)
    {
        lo &= 2147483647;
        ++lo;
    }

    Seed = lo;
    return (Seed);
}



// rand31f() - Return FAST 31-bit random number (pointer to see is first
argument).
static asm UInt32 rand31f(UInt32 *pSeed)
{
    link        a6, #0
    movem.l     d3-d4/a2, -(a7)
    movea.l     8(a6), a2           // a2 = pSeed

    move.l      (a2), d4            // d4 = *pSeed
    move.l      #16807, d1          // d1 = 16807

//  lo = 16807 * (*pSeed & 0xFFFF);
    move.l      d4, d3              // d3 = *pSeed
    mulu.w      d1, d3              // d3 = 16807 * *pSeed = lo

//  hi = 16807 * (*pSeed >> 16);
    swap        d4                  // d4 = *pSeed >> 16
    mulu.w      d1, d4              // d4 = 16807 * (*pSeed >> 16) = hi

//  lo += (hi & 0x7FFF) << 16;
    move.l      d4, d0              // d0 = hi
    andi.l      #0x7fff, d0         // hi &= 0x7FFF
    swap        d0                  // hi <<= 16
    add.l       d0, d3              // lo += (hi & 0x7FFF) << 16

//  if (lo > 2147483647)
//  {
//      lo &= 2147483647;
//      ++lo;
//  }
    tst.l       d3                  // test d3 lo
    bpl.s       r31b                // skip if positive
    bclr        #31, d3             // mask off sign (overflow) bit
    addq.l      #1, d3              // lo++
r31b:

//  lo += hi >> 15;
    moveq.l     #15, d0
    lsr.l       d0, d4              // hi >>= 15
    add.l       d4, d3              // lo += hi >> 15

//  if (lo > 2147483647)
//  {
//      lo &= 2147483647;
//      ++lo;
//  }
    tst.l       d3                  // test d3 lo
    bpl.s       r31c                // skip if positive
    bclr        #31, d3             // mask off sign (overflow) bit
    addq.l      #1, d3              // lo++
r31c:

//  return (*pSeed = lo);
    move.l    d3, (a2)              // *pSeed = lo
    move.l    d3, d0                // return lo

    movem.l     (a7)+,d3-d4/a2
    unlk        a6
    rts
}
-------------------------------------------------


-----Original Message-----
From: Nils Raschke [mailto:[EMAIL PROTECTED]]
Sent: Tuesday November 20, 2001 09:59
To: Palm Developer Forum
Subject: get a random number within a specified range


Hello,

I like to get a random number in the range from 1 to 6.

The function sysRandom() don�t allow to specify a range or an upper limit
(the highest possible number is defined in sysRandomMax, but I don�t think I
should change there anything).

Is there a way to get the desired result directly from sysRandom()?

Or, do I have to trim the value that I get from sysRandom() to my needs (if
so, in what header file I have to look to get the functions to get just the
first unit (numbers 0-9) of a number)?

Thanks in advance,
Nils

--
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