CBuffFileStream/CreateRandExpNumbers.c

/*
    File:       CreateRandExpNumbers.c
 
    Contains:   Random number utilities.
 
    Written by: Steve Bollinger
 
    Copyright:  Copyright (c) 1999 Apple Computer, Inc., All Rights Reserved.
 
                You may incorporate this Apple sample source code into your program(s) without
                restriction. This Apple sample source code has been provided "AS IS" and the
                responsibility for its operation is yours. You are not permitted to redistribute
                this Apple sample source code as "Apple sample source code" after having made
                changes. If you're going to re-distribute the source, we require that you make
                it clear in the source that the code was descended from Apple sample source
                code, but that you've made changes.
 
*/
 
#include <DateTimeUtils.h>
#include <LowMem.h>
 
#include "CreateRandExpNumbers.h"
 
static unsigned GetRandom15Bit(void);
static unsigned long GetRandom32Bit(void);
 
void RandomlySeedRandom(void)
{
    unsigned long       secs;
 
    GetDateTime(&secs);
    LMSetRndSeed(secs);
}
 
void CreateRandomExpNumbers(unsigned long *towhere, unsigned long maxval, unsigned long numnumbers)
{
// Here's the story, we generate random numbers by concatenating series of random bits
// of the length of the magnitude of the maxval and throwing out all values larger than
// the max.
    static unsigned long    exponentValues[32] =
    { 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff, 0x7ff, 0xfff,
      0x1fff, 0x3fff, 0x7fff, 0xffff, 0x1ffff, 0x3ffff, 0x7ffff, 0xfffff, 0x1fffff,
      0x3fffff, 0x7fffff, 0xffffff, 0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff,
      0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff };
 
    unsigned                maxmagnitude = 0;
    unsigned long           curnumber;
    unsigned                expmagnitude = 0;
 
// First, find the magnitude of maxval
 
    while (maxval > exponentValues[maxmagnitude])
    {
        maxmagnitude++;
    }
 
// Now, find the magnitude of the magnitude
    while (maxmagnitude > exponentValues[expmagnitude])
    {
        expmagnitude++;
    }
 
// Now, we need to generate exponents and values
    for (curnumber = 0; curnumber < numnumbers; curnumber++)
    {
        unsigned            randmagnitude;
        unsigned long       randval;
 
    // First, calculate random magnitude
        do
        {
            randmagnitude = GetRandom15Bit() & exponentValues[expmagnitude];
        } while (randmagnitude > maxmagnitude);
 
    // Now create a random 32 bit number and mask it down.
        do
        {
            randval = GetRandom32Bit() & exponentValues[randmagnitude];
        } while (randval > maxval);
 
    // Whew, we got one number! Store it and move on.
        towhere[curnumber] = randval;
    }
}
 
unsigned GetRandom15Bit(void)
{
    short           val;
 
    do
    {
        val = Random();
 
        if (0 == val)
            val = -2;           // 0 sux, make it out of range
        if (-1 == val)
            val = 0;            // but -1 is okay.
 
    } while (val < 0 || val > 32767);
 
    return (unsigned) val;
}
 
unsigned long GetRandom32Bit(void)
{
    return (GetRandom15Bit() << 17) |
           (GetRandom15Bit() << 2) |
           (GetRandom15Bit() & 0x3);
}