home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / statlib.zip / RANDOM.C next >
C/C++ Source or Header  |  2000-11-07  |  2KB  |  64 lines

  1. /***********************************************************
  2.   Verbesserter Zufallsgenerator nach Knuth / Sedgewick
  3.   für ANSI-C-Compiler, weitgehend plattformunabhängig
  4.   (c) 1998, 2000 Heinz Repp
  5. ***********************************************************/
  6.  
  7. #include <limits.h>
  8. #include <stdlib.h>
  9.  
  10. #undef RAND_MAX
  11. #define RAND_MAX INT_MAX
  12.  
  13. static int lastrand[55], randlast = -1;
  14.  
  15.  
  16. void srand (unsigned int seed) /* Methode: lineare Kongruenz */
  17. {
  18.   unsigned int gen1, gen2;
  19.   randlast = -1;
  20.   gen2 = seed;
  21.   do
  22.   {
  23.     gen1 = ((UINT_MAX / 3137) * 200 + 21) * gen2 + 1;
  24.     gen2 = ((UINT_MAX / 3137) * 200 + 21) * gen1 + 1;
  25.     lastrand[++randlast] = (int) (((gen1 >> 10) ^ gen2) & INT_MAX);
  26.   } while (randlast < 54);
  27. }
  28.  
  29.  
  30. int rand (void)      /* Generator mit additiver Kongruenz */
  31. {
  32.   if (randlast < 0)
  33.     srand (1);
  34.   randlast = (randlast + 1) % 55;
  35.   return lastrand[randlast] =
  36.     (lastrand[randlast] + lastrand[(randlast + 24) % 55]) & INT_MAX;
  37. }
  38.  
  39.  
  40. int irand (int range)
  41. {
  42.   unsigned int rng, sav, lft, res; /* we need one bit more */
  43.  
  44.   rng = (unsigned) range;
  45.   sav = (unsigned) rand ();
  46.   lft = sizeof (int) * 8 - 1;      /* int bits without sign */
  47.   res = rng >> 1;                  /* preload with range / 2 */
  48.  
  49.   while (rng)                      /* add range * rand () */
  50.   {
  51.     if (rng & 1)
  52.       res += sav;
  53.     res >>= 1;
  54.     rng >>= 1;
  55.     lft--;
  56.   }
  57.   return (int) (res >> lft);
  58. }
  59.  
  60. double frand (void)
  61. {
  62.   return (double) rand() / (INT_MAX + 1.0);
  63. }
  64.