Back to index

php5  5.3.10
Defines | Functions
rand.c File Reference
#include <stdlib.h>
#include "php.h"
#include "php_math.h"
#include "php_rand.h"
#include "php_lcg.h"
#include "basic_functions.h"

Go to the source code of this file.

Defines

#define N   MT_N /* length of state vector */
#define M   (397) /* a period parameter */
#define hiBit(u)   ((u) & 0x80000000U) /* mask all but highest bit of u */
#define loBit(u)   ((u) & 0x00000001U) /* mask all but lowest bit of u */
#define loBits(u)   ((u) & 0x7FFFFFFFU) /* mask the highest bit of u */
#define mixBits(u, v)   (hiBit(u)|loBits(v)) /* move hi bit of u to hi bit of v */
#define twist(m, u, v)   (m ^ (mixBits(u,v)>>1) ^ ((php_uint32)(-(php_int32)(loBit(u))) & 0x9908b0dfU))

Functions

PHPAPI void php_srand (long seed TSRMLS_DC)
PHPAPI long php_rand (TSRMLS_D)
static void php_mt_initialize (php_uint32 seed, php_uint32 *state)
static void php_mt_reload (TSRMLS_D)
PHPAPI void php_mt_srand (php_uint32 seed TSRMLS_DC)
PHPAPI php_uint32 php_mt_rand (TSRMLS_D)
 PHP_FUNCTION (srand)
 PHP_FUNCTION (mt_srand)
 PHP_FUNCTION (rand)
 PHP_FUNCTION (mt_rand)
 PHP_FUNCTION (getrandmax)
 PHP_FUNCTION (mt_getrandmax)

Define Documentation

#define hiBit (   u)    ((u) & 0x80000000U) /* mask all but highest bit of u */

Definition at line 145 of file rand.c.

#define loBit (   u)    ((u) & 0x00000001U) /* mask all but lowest bit of u */

Definition at line 146 of file rand.c.

#define loBits (   u)    ((u) & 0x7FFFFFFFU) /* mask the highest bit of u */

Definition at line 147 of file rand.c.

#define M   (397) /* a period parameter */

Definition at line 144 of file rand.c.

#define mixBits (   u,
 
)    (hiBit(u)|loBits(v)) /* move hi bit of u to hi bit of v */

Definition at line 148 of file rand.c.

#define N   MT_N /* length of state vector */

Definition at line 143 of file rand.c.

#define twist (   m,
  u,
 
)    (m ^ (mixBits(u,v)>>1) ^ ((php_uint32)(-(php_int32)(loBit(u))) & 0x9908b0dfU))

Definition at line 150 of file rand.c.


Function Documentation

PHP_FUNCTION ( srand  )

Definition at line 231 of file rand.c.

{
       long seed = 0;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &seed) == FAILURE)
              return;

       if (ZEND_NUM_ARGS() == 0)
              seed = GENERATE_SEED();

       php_srand(seed TSRMLS_CC);
}

Here is the call graph for this function:

PHP_FUNCTION ( mt_srand  )

Definition at line 247 of file rand.c.

{
       long seed = 0;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &seed) == FAILURE) 
              return;

       if (ZEND_NUM_ARGS() == 0)
              seed = GENERATE_SEED();

       php_mt_srand(seed TSRMLS_CC);
}

Here is the call graph for this function:

PHP_FUNCTION ( rand  )

Definition at line 290 of file rand.c.

{
       long min;
       long max;
       long number;
       int  argc = ZEND_NUM_ARGS();

       if (argc != 0 && zend_parse_parameters(argc TSRMLS_CC, "ll", &min, &max) == FAILURE)
              return;

       number = php_rand(TSRMLS_C);
       if (argc == 2) {
              RAND_RANGE(number, min, max, PHP_RAND_MAX);
       }

       RETURN_LONG(number);
}

Here is the call graph for this function:

PHP_FUNCTION ( mt_rand  )

Definition at line 311 of file rand.c.

{
       long min;
       long max;
       long number;
       int  argc = ZEND_NUM_ARGS();

       if (argc != 0) {
              if (zend_parse_parameters(argc TSRMLS_CC, "ll", &min, &max) == FAILURE) {
                     return;
              } else if (max < min) {
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "max(%ld) is smaller than min(%ld)", max, min);
                     RETURN_FALSE;
              }
       }

       if (!BG(mt_rand_is_seeded)) {
              php_mt_srand(GENERATE_SEED() TSRMLS_CC);
       }

       /*
        * Melo: hmms.. randomMT() returns 32 random bits...
        * Yet, the previous php_rand only returns 31 at most.
        * So I put a right shift to loose the lsb. It *seems*
        * better than clearing the msb. 
        * Update: 
        * I talked with Cokus via email and it won't ruin the algorithm
        */
       number = (long) (php_mt_rand(TSRMLS_C) >> 1);
       if (argc == 2) {
              RAND_RANGE(number, min, max, PHP_MT_RAND_MAX);
       }

       RETURN_LONG(number);
}

Here is the call graph for this function:

PHP_FUNCTION ( getrandmax  )

Definition at line 350 of file rand.c.

PHP_FUNCTION ( mt_getrandmax  )

Definition at line 362 of file rand.c.

{
       if (zend_parse_parameters_none() == FAILURE) {
              return;
       }

       /*
        * Melo: it could be 2^^32 but we only use 2^^31 to maintain
        * compatibility with the previous php_rand
        */
       RETURN_LONG(PHP_MT_RAND_MAX); /* 2^^31 */
}
static void php_mt_initialize ( php_uint32  seed,
php_uint32 *  state 
) [inline, static]

Definition at line 154 of file rand.c.

{
       /* Initialize generator state with seed
          See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.
          In previous versions, most significant bits (MSBs) of the seed affect
          only MSBs of the state array.  Modified 9 Jan 2002 by Makoto Matsumoto. */

       register php_uint32 *s = state;
       register php_uint32 *r = state;
       register int i = 1;

       *s++ = seed & 0xffffffffU;
       for( ; i < N; ++i ) {
              *s++ = ( 1812433253U * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffU;
              r++;
       }
}

Here is the caller graph for this function:

PHPAPI php_uint32 php_mt_rand ( TSRMLS_D  )

Definition at line 209 of file rand.c.

{
       /* Pull a 32-bit integer from the generator state
          Every other access function simply transforms the numbers extracted here */
       
       register php_uint32 s1;

       if (BG(left) == 0) {
              php_mt_reload(TSRMLS_C);
       }
       --BG(left);
              
       s1 = *BG(next)++;
       s1 ^= (s1 >> 11);
       s1 ^= (s1 <<  7) & 0x9d2c5680U;
       s1 ^= (s1 << 15) & 0xefc60000U;
       return ( s1 ^ (s1 >> 18) );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void php_mt_reload ( TSRMLS_D  ) [inline, static]

Definition at line 175 of file rand.c.

{
       /* Generate N new values in state
          Made clearer and faster by Matthew Bellew (matthew.bellew@home.com) */

       register php_uint32 *state = BG(state);
       register php_uint32 *p = state;
       register int i;

       for (i = N - M; i--; ++p)
              *p = twist(p[M], p[0], p[1]);
       for (i = M; --i; ++p)
              *p = twist(p[M-N], p[0], p[1]);
       *p = twist(p[M-N], p[0], state[0]);
       BG(left) = N;
       BG(next) = state;
}

Here is the caller graph for this function:

PHPAPI void php_mt_srand ( php_uint32 seed  TSRMLS_DC)

Definition at line 196 of file rand.c.

{
       /* Seed the generator with a simple uint32 */
       php_mt_initialize(seed, BG(state));
       php_mt_reload(TSRMLS_C);

       /* Seed only once */
       BG(mt_rand_is_seeded) = 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI long php_rand ( TSRMLS_D  )

Definition at line 63 of file rand.c.

{
       long ret;

       if (!BG(rand_is_seeded)) {
              php_srand(GENERATE_SEED() TSRMLS_CC);
       }

#ifdef ZTS
       ret = php_rand_r(&BG(rand_seed));
#else
# if defined(HAVE_RANDOM)
       ret = random();
# elif defined(HAVE_LRAND48)
       ret = lrand48();
# else
       ret = rand();
# endif
#endif

       return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI void php_srand ( long seed  TSRMLS_DC)

Definition at line 42 of file rand.c.

{
#ifdef ZTS
       BG(rand_seed) = (unsigned int) seed;
#else
# if defined(HAVE_SRANDOM)
       srandom((unsigned int) seed);
# elif defined(HAVE_SRAND48)
       srand48(seed);
# else
       srand((unsigned int) seed);
# endif
#endif

       /* Seed only once */
       BG(rand_is_seeded) = 1;
}

Here is the caller graph for this function: