comparison src/fns.c @ 6376:3fe339cf2dde

(Frandom): Eliminate bias in random number generator.
author Karl Heuer <kwzh@gnu.org>
date Wed, 16 Mar 1994 06:48:19 +0000
parents 4ef6b636dc99
children a4bf4dba3ace
comparison
equal deleted inserted replaced
6375:212dcd2c06e4 6376:3fe339cf2dde
53 With argument t, set the random number seed from the current time and pid.") 53 With argument t, set the random number seed from the current time and pid.")
54 (limit) 54 (limit)
55 Lisp_Object limit; 55 Lisp_Object limit;
56 { 56 {
57 int val; 57 int val;
58 unsigned long denominator;
58 extern long random (); 59 extern long random ();
59 extern srandom (); 60 extern srandom ();
60 extern long time (); 61 extern long time ();
61 62
62 if (EQ (limit, Qt)) 63 if (EQ (limit, Qt))
63 srandom (getpid () + time (0)); 64 srandom (getpid () + time (0));
64 val = random (); 65 if (XTYPE (limit) == Lisp_Int && XINT (limit) > 0)
65 if (XTYPE (limit) == Lisp_Int && XINT (limit) != 0)
66 { 66 {
67 /* Try to take our random number from the higher bits of VAL, 67 /* Try to take our random number from the higher bits of VAL,
68 not the lower, since (says Gentzel) the low bits of `random' 68 not the lower, since (says Gentzel) the low bits of `random'
69 are less random than the higher ones. */ 69 are less random than the higher ones. We do this by using the
70 val &= 0xfffffff; /* Ensure positive. */ 70 quotient rather than the remainder. At the high end of the RNG
71 val >>= 5; 71 it's possible to get a quotient larger than limit; discarding
72 if (XINT (limit) < 10000) 72 these values eliminates the bias that would otherwise appear
73 val >>= 6; 73 when using a large limit. */
74 val %= XINT (limit); 74 denominator = (unsigned long)0x80000000 / XFASTINT (limit);
75 } 75 do
76 val = (random () & 0x7fffffff) / denominator;
77 while (val >= limit);
78 }
79 else
80 val = random ();
76 return make_number (val); 81 return make_number (val);
77 } 82 }
78 83
79 /* Random data-structure functions */ 84 /* Random data-structure functions */
80 85