home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / fontutils-0.6-base.tgz / fontutils-0.6-base.tar / fsf / fontutils / lib / rand.c < prev    next >
C/C++ Source or Header  |  1992-08-24  |  2KB  |  71 lines

  1. /* rand.c: a simple pseudo-random number generator.
  2.  
  3. Copyright (C) 1992 Free Software Foundation, Inc.
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9.  
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include "config.h"
  20.  
  21. #include "rand.h"
  22.  
  23.  
  24. /* Current state of the random number generator.  ANSI C says that the
  25.    default should be as if `srand' was called with the value 1.  At all
  26.    times this will be a random number between 1 and RAND_MAX+1.  */
  27. static long rand_state = 2;
  28.  
  29.  
  30. /* Set the state.  It's ok if `seed' doesn't fit in a long, since we
  31.    check for negative values before we return anything.  On the other
  32.    hand, we cannot allow our state to become zero, since then we will
  33.    produce zero forever.  */
  34.  
  35. void
  36. seed_rand (unsigned seed)
  37. {
  38.   rand_state = seed + 1;
  39. }
  40.  
  41.  
  42. /* Return a pseudo-random number based on `x' in the range [0, RAND_MAX].
  43.    We use the Ghostscript computation (from the function `zrand' in the
  44.    file `zmath.c').  */
  45.  
  46. int
  47. k_rand ()
  48. {
  49.   /* We use an algorithm from CACM 31(10), pp. 1192-1201, October 1988. 
  50.      According to a posting by Ed Taft on comp.lang.postscript, Level 2
  51.      (Adobe) PostScript interpreters use this algorithm too:
  52.  
  53.             x[n+1] = (16807 * x[n]) mod (2^31 - 1)
  54.      
  55.      The complication ensues from the fact that the multiplication may
  56.      lead to a 46-bit number.  */
  57.  
  58. #define A 16807
  59. #define M 0x7fffffff
  60. #define Q 127773            /* M / A */
  61. #define R 2836                /* M % A */
  62.   rand_state = A * (rand_state % Q) - R * (rand_state / Q);
  63.   while ( rand_state <= 0 ) rand_state += M;
  64.   
  65.   /* OK, `rand_state' is our new random number between 1 and 2^31 - 1.
  66.      Now we have to subtract one, so that we return a number in the
  67.      range zero to RAND_MAX (inclusive).  We obviously must define our
  68.      RAND_MAX to be 2^31 - 2, which we do (in `rand.h').  */
  69.   return rand_state - 1;
  70. }
  71.