- uint8_t *buf = buf_;
- uint8_t *s;
- uint8_t i, j;
-
- assert (rng != 0);
-
- s = rng->s;
- i = rng->i;
- j = rng->j;
- while (size-- > 0)
- {
- i += 1;
- j += s[i];
- swap_byte (s + i, s + j);
- *buf++ = s[(s[i] + s[j]) & 255];
- }
- rng->i = i;
- rng->j = j;
-}
-
-/* Returns a random int in the range [0, INT_MAX]. */
-int
-rng_get_int (struct rng *rng)
-{
- int value;
-
- do
- {
- rng_get_bytes (rng, &value, sizeof value);
- value = abs (value);
- }
- while (value < 0);
-
- return value;
-}
-
-/* Returns a random unsigned in the range [0, UINT_MAX]. */
-unsigned
-rng_get_unsigned (struct rng *rng)
-{
- unsigned value;
-
- rng_get_bytes (rng, &value, sizeof value);
- return value;
-}
-
-/* Returns a random number from the uniform distribution with
- range [0,1). */
-double
-rng_get_double (struct rng *rng)
-{
- for (;;)
- {
- unsigned long ulng;
- double dbl;
-
- rng_get_bytes (rng, &ulng, sizeof ulng);
- dbl = ulng / (ULONG_MAX + 1.0);
- if (dbl >= 0 && dbl < 1)
- return dbl;
- }
-}
-
-/* Returns a random number from the distribution with mean 0 and
- standard deviation 1. (Multiply the result by the desired
- standard deviation, then add the desired mean.) */
-double
-rng_get_double_normal (struct rng *rng)
-{
- /* Knuth, _The Art of Computer Programming_, Vol. 2, 3.4.1C,
- Algorithm P. */
- double this_normal;
-
- if (rng->next_normal != NOT_DOUBLE)
- {
- this_normal = rng->next_normal;
- rng->next_normal = NOT_DOUBLE;
- }
- else
- {
- double v1, v2, s;
-
- do
- {
- double u1 = rng_get_double (rng);
- double u2 = rng_get_double (rng);
- v1 = 2.0 * u1 - 1.0;
- v2 = 2.0 * u2 - 1.0;
- s = v1 * v1 + v2 * v2;
- }
- while (s >= 1);
-
- this_normal = v1 * sqrt (-2. * log (s) / s);
- rng->next_normal = v2 * sqrt (-2. * log (s) / s);
- }
-
- return this_normal;