home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #26 / NN_1992_26.iso / spool / comp / lang / c / 16166 < prev    next >
Encoding:
Internet Message Format  |  1992-11-08  |  2.9 KB

  1. Path: sparky!uunet!spool.mu.edu!agate!dog.ee.lbl.gov!horse.ee.lbl.gov!torek
  2. From: torek@horse.ee.lbl.gov (Chris Torek)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: Random Number Generator
  5. Date: 8 Nov 1992 10:58:19 GMT
  6. Organization: Lawrence Berkeley Laboratory, Berkeley
  7. Lines: 70
  8. Message-ID: <27296@dog.ee.lbl.gov>
  9. References: <11781@hq.hq.af.mil> <1992Oct22.181426.59@front.se> <26939@dog.ee.lbl.gov> <1992Nov6.223901.11603@athena.mit.edu>
  10. Reply-To: torek@horse.ee.lbl.gov (Chris Torek)
  11. NNTP-Posting-Host: 128.3.112.15
  12.  
  13. >In article <26939@dog.ee.lbl.gov> I wrote:
  14. >> Time for another Netnews Rerun....
  15.  
  16. In article <1992Nov6.223901.11603@athena.mit.edu> scs@adam.mit.edu
  17. (Steve Summit) writes:
  18. >Chris may be thinking of an earlier draft.  The example
  19. >implementation in the published ANSI standard (ANSI X3.159-1989,
  20. >sec. 4.10.2.2, p. 155) is not a pure linear congruential random
  21. >number generator; rather, it is a LCRNG with a 32-bit (or more)
  22. >state value which returns 15 bits from the *top* (most
  23. >significant) half.  Therefore, its actual return values are
  24. >*not* subject to these particularly unfortunate regularities.
  25. >(To recap: the low-order N bits of a pure LCRNG repeat with
  26. >period 2-to-the-N.)
  27.  
  28. Several comments:
  29.  
  30. This is a problem with netnews reruns:  They get out of date.  I try to
  31. take time to edit them, but....
  32.  
  33. The parenthetical recap is not quite right.  Rather, given an LCRNG
  34. of the form:
  35.  
  36.     X[i+1] = (X[i] * a + c) mod m
  37.  
  38. (which has period <= m; if a and c are well-chosen, the period is
  39. exactly m), we define a new sequence:
  40.  
  41.     Y[j] = X[j] mod d
  42.  
  43. If m is congruent to 0 mod d (i.e., m % d = 0), the sequence in Y
  44. will repeat with period <= d.  The definition of Y corresponds
  45. perfectly with taking rand() % d (think of X[j] as the j'th return
  46. value from rand()).
  47.  
  48. Since typical C implementations of rand() use LCRNG's with 2^k (for
  49. integer k, usually 16 or 32) as their `m', and since 2^k mod 2^N is 0,
  50. the low order bits repeat with period 2^N.  But this only holds when
  51. m = 2^k, not for LCRNG's in general.
  52.  
  53. >In other words, the prevailing advice is to consign rand() % N to
  54. >the same dustbin that gets() has been demoted to: the code is
  55. >there, and it is theoretically legal to use it, but you mustn't.
  56.  
  57. Right.
  58.  
  59. >I happen to think that the rand() % N problem is so common, and is
  60. >so easily made by the unwary, that it's worth fixing ...
  61.  
  62. This is rather difficult (see your own note 2).  For what it is worth,
  63. I ran a few simple 2-d scatter plot tests on the `ANSI C' generator
  64. (which, incidentally, appears below), and saw no obvious patterns, but
  65. I would want to know more about it before trusting it much.
  66.  
  67. /* ANSI C `portable random number generator' */
  68. static unsigned long int next = 1;
  69.  
  70. int rand(void)        /* RAND_MAX assumed to be 32767 */
  71. {
  72.     next = next * 1103515245 + 12345;
  73.     return (unsigned int)(next / 65536) % 32768;
  74. }
  75.  
  76. void srand(unsigned int seed)
  77. {
  78.     next = seed;
  79. }
  80. -- 
  81. In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 510 486 5427)
  82. Berkeley, CA        Domain:    torek@ee.lbl.gov
  83.