/[guile]/guile/guile-core/libguile/random.c
ViewVC logotype

Diff of /guile/guile-core/libguile/random.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.51 by hanwen, Fri Aug 16 22:01:10 2002 UTC revision 1.52 by mdj, Mon Mar 3 13:19:46 2003 UTC
# Line 1  Line 1 
1  /* Copyright (C) 1999,2000,2001 Free Software Foundation, Inc.  /* Copyright (C) 1999,2000,2001, 2003 Free Software Foundation, Inc.
2   * This program is free software; you can redistribute it and/or modify   * This program is free software; you can redistribute it and/or modify
3   * it under the terms of the GNU General Public License as published by   * it under the terms of the GNU General Public License as published by
4   * the Free Software Foundation; either version 2, or (at your option)   * the Free Software Foundation; either version 2, or (at your option)
# Line 265  scm_c_random (scm_t_rstate *state, unsig Line 265  scm_c_random (scm_t_rstate *state, unsig
265    return r;    return r;
266  }  }
267    
268    /*
269      SCM scm_c_random_bignum (scm_t_rstate *state, SCM m)
270    
271      Takes a random state (source of random bits) and a bignum m.
272      Returns a bignum b, 0 <= b < m.
273    
274      It does this by allocating a bignum b with as many base 65536 digits
275      as m, filling b with random bits (in 32 bit chunks) up to the most
276      significant 1 in m, and, finally checking if the resultant b is too
277      large (>= m).  If too large, we simply repeat the process again.  (It
278      is important to throw away all generated random bits if b >= m,
279      otherwise we'll end up with a distorted distribution.)
280    
281    */
282    
283  SCM  SCM
284  scm_c_random_bignum (scm_t_rstate *state, SCM m)  scm_c_random_bignum (scm_t_rstate *state, SCM m)
285  {  {
# Line 272  scm_c_random_bignum (scm_t_rstate *state Line 287  scm_c_random_bignum (scm_t_rstate *state
287    int i, nd;    int i, nd;
288    LONG32 *bits, mask, w;    LONG32 *bits, mask, w;
289    nd = SCM_NUMDIGS (m);    nd = SCM_NUMDIGS (m);
290    /* calculate mask for most significant digit */    /* Compute a 32-bit bitmask for use when filling bits into the most
291         significant long word in b's bit space.  A combination of
292         conditionals and an 8-bit lookup table (scm_masktab) is used.
293      */
294  #if SIZEOF_INT == 4  #if SIZEOF_INT == 4
295    /* 16 bit digits */    /* 16 bit digits */
296    if (nd & 1)    if (nd & 1)
# Line 298  scm_c_random_bignum (scm_t_rstate *state Line 316  scm_c_random_bignum (scm_t_rstate *state
316                   ? scm_masktab[w >> 16] << 16 | 0xffff                   ? scm_masktab[w >> 16] << 16 | 0xffff
317                   : scm_masktab[w >> 24] << 24 | 0xffffff));                   : scm_masktab[w >> 24] << 24 | 0xffffff));
318      }      }
319      /* allocate b and assign the bit space address to the variable "bits" */
320    b = scm_i_mkbig (nd, 0);    b = scm_i_mkbig (nd, 0);
321    bits = (LONG32 *) SCM_BDIGITS (b);    bits = (LONG32 *) SCM_BDIGITS (b);
322    do    do
323      {      {
324        i = nd;        i = nd;
325        /* treat most significant digit specially */        /* generate the most significant bits using the mask */
326  #if SIZEOF_INT == 4  #if SIZEOF_INT == 4
327        /* 16 bit digits */        /* 16 bit digits */
328        if (i & 1)        if (i & 1)
# Line 328  scm_c_random_bignum (scm_t_rstate *state Line 347  scm_c_random_bignum (scm_t_rstate *state
347        /* now fill up the rest of the bignum */        /* now fill up the rest of the bignum */
348        while (i)        while (i)
349          bits[--i] = scm_the_rng.random_bits (state);          bits[--i] = scm_the_rng.random_bits (state);
350          /* use scm_i_normbig to cut away leading zeros and/or convert to inum */
351        b = scm_i_normbig (b);        b = scm_i_normbig (b);
352        if (SCM_INUMP (b))        if (SCM_INUMP (b))
353          return b;          return b;
354          /* if b >= m, regenerate b (it is important to regenerates all
355             bits in order not to get a distorted distribution)
356          */
357      } while (scm_bigcomp (b, m) <= 0);      } while (scm_bigcomp (b, m) <= 0);
358    return b;    return b;
359  }  }

Legend:
Removed from v.1.51  
changed lines
  Added in v.1.52

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26