⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 random.c

📁 嵌入式GUI OpenGL源代码。OpenGL是嵌入式开发中常用的一种GUI系统。
💻 C
📖 第 1 页 / 共 2 页
字号:
 * that are exactly rand_sep places apart.  Lastly, it cycles the state
 * information a given number of times to get rid of any initial dependencies
 * introduced by the L.C.R.N.G.
 * Note that the initialization of randtbl[] for default usage relies on
 * values produced by this routine.
 */

void
srandom( x )
    unsigned            x;
{
        register  int           i;

        if(  rand_type  ==  TYPE_0  )  {
            state[ 0 ] = (long) x;
        }
        else  {
            state[ 0 ] = (long) x;
            for( i = 1; i < rand_deg; i++ )  {
                state[i] = 1103515245*state[i - 1] + 12345;
            }
            fptr = &state[ rand_sep ];
            rptr = &state[ 0 ];
            for( i = 0; i < 10*rand_deg; i++ )  random();
        }
}



/*
 * initstate:
 * Initialize the state information in the given array of n bytes for
 * future random number generation.  Based on the number of bytes we
 * are given, and the break values for the different R.N.G.'s, we choose
 * the best (largest) one we can and set things up for it.  srandom() is
 * then called to initialize the state information.
 * Note that on return from srandom(), we set state[-1] to be the type
 * multiplexed with the current value of the rear pointer; this is so
 * successive calls to initstate() won't lose this information and will
 * be able to restart with setstate().
 * Note: the first thing we do is save the current state, if any, just like
 * setstate() so that it doesn't matter when initstate is called.
 * Returns a pointer to the old state.
 */

char  *
initstate( seed, arg_state, n )

    unsigned            seed;                   /* seed for R. N. G. */
    char                *arg_state;             /* pointer to state array */
    size_t              n;                      /* # bytes of state info */
{
        register  char          *ostate         = (char *)( &state[ -1 ] );

        if(  rand_type  ==  TYPE_0  )  state[ -1 ] = rand_type;
        else  state[ -1 ] = MAX_TYPES*(rptr - state) + rand_type;
        if(  n  <  BREAK_1  )  {
            if(  n  <  BREAK_0  )  {
                fprintf( stderr, "initstate: not enough state (%d bytes) with which to do jack; ignored.\n", n );
                return 0;
            }
            rand_type = TYPE_0;
            rand_deg = DEG_0;
            rand_sep = SEP_0;
        }
        else  {
            if(  n  <  BREAK_2  )  {
                rand_type = TYPE_1;
                rand_deg = DEG_1;
                rand_sep = SEP_1;
            }
            else  {
                if(  n  <  BREAK_3  )  {
                    rand_type = TYPE_2;
                    rand_deg = DEG_2;
                    rand_sep = SEP_2;
                }
                else  {
                    if(  n  <  BREAK_4  )  {
                        rand_type = TYPE_3;
                        rand_deg = DEG_3;
                        rand_sep = SEP_3;
                    }
                    else  {
                        rand_type = TYPE_4;
                        rand_deg = DEG_4;
                        rand_sep = SEP_4;
                    }
                }
            }
        }
        state = &(  ( (long *)arg_state )[1]  );        /* first location */
        end_ptr = &state[ rand_deg ];   /* must set end_ptr before srandom */
        srandom( seed );
        if(  rand_type  ==  TYPE_0  )  state[ -1 ] = rand_type;
        else  state[ -1 ] = MAX_TYPES*(rptr - state) + rand_type;
        return( ostate );
}



/*
 * setstate:
 * Restore the state from the given state array.
 * Note: it is important that we also remember the locations of the pointers
 * in the current state information, and restore the locations of the pointers
 * from the old state information.  This is done by multiplexing the pointer
 * location into the zeroeth word of the state information.
 * Note that due to the order in which things are done, it is OK to call
 * setstate() with the same state as the current state.
 * Returns a pointer to the old state information.
 */

char  *
setstate( arg_state )

    const char          *arg_state;
{
        register  long          *new_state      = (long *)arg_state;
        register  int           type            = (int)new_state[0]%MAX_TYPES;
        register  int           rear            = (int)new_state[0]/MAX_TYPES;
        char                    *ostate         = (char *)( &state[ -1 ] );

        if(  rand_type  ==  TYPE_0  )  state[ -1 ] = rand_type;
        else  state[ -1 ] = MAX_TYPES*(rptr - state) + rand_type;
        switch(  type  )  {
            case  TYPE_0:
            case  TYPE_1:
            case  TYPE_2:
            case  TYPE_3:
            case  TYPE_4:
                rand_type = type;
                rand_deg = degrees[ type ];
                rand_sep = seps[ type ];
                break;

            default:
                fprintf( stderr, "setstate: state info has been munged; not changed.\n" );
        }
        state = &new_state[ 1 ];
        if(  rand_type  !=  TYPE_0  )  {
            rptr = &state[ rear ];
            fptr = &state[ (rear + rand_sep)%rand_deg ];
        }
        end_ptr = &state[ rand_deg ];           /* set end_ptr too */
        return( ostate );
}



/*
 * random:
 * If we are using the trivial TYPE_0 R.N.G., just do the old linear
 * congruential bit.  Otherwise, we do our fancy trinomial stuff, which is the
 * same in all ther other cases due to all the global variables that have been
 * set up.  The basic operation is to add the number at the rear pointer into
 * the one at the front pointer.  Then both pointers are advanced to the next
 * location cyclically in the table.  The value returned is the sum generated,
 * reduced to 31 bits by throwing away the "least random" low bit.
 * Note: the code takes advantage of the fact that both the front and
 * rear pointers can't wrap on the same call by not testing the rear
 * pointer if the front one has wrapped.
 * Returns a 31-bit random number.
 */

long
random(void)
{
        long            i;
        
        if(  rand_type  ==  TYPE_0  )  {
            i = state[0] = ( state[0]*1103515245 + 12345 )&0x7fffffff;
        }
        else  {
            *fptr += *rptr;
            i = (*fptr >> 1)&0x7fffffff;        /* chucking least random bit */
            if(  ++fptr  >=  end_ptr  )  {
                fptr = state;
                ++rptr;
            }
            else  {
                if(  ++rptr  >=  end_ptr  )  rptr = state;
            }
        }
        return( i );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -