# Bug in module random (stdlib-1.16.5, R13B04)

Florian Schintke <>
Fri Jun 11 17:26:13 CEST 2010

```Hi,

* What steps will reproduce the problem?

random:seed({0,0,0}).
random:uniform(10000).
random:uniform(10000).
random:uniform(10000).
random:uniform(10000).

* What is the expected output? What do you see instead?

Expected output are random numbers in the range of 1..10000.
Instead all calls to uniform:random(10000) return 1.

In general: Randomness of random:uniform is restricted, when a single
element of the seed contains a 0 (which regularily is the case when
erlang:now() is used for seeding).

* What version of the product are you using? On what operating system?

stdlib-1.16.5, R13B04

stdlib-1.16.5/src/random.erl is supposed to implement the algorithm by
B. A. Wichmann and I. D. Hill See "An efficient and portable
pseudo-random number generator", Journal of Applied
Statistics. AS183. 1982. Also Byte March 1987.

In this article each element of the seed has to be a *positive*
integer in the range 1..30000.

If one element in the seed is 0, this will never change when getting
random numbers, as a multiplication with 0 always returns 0.  So
randomness is broken in this case (see random:uniform()).

uniform() ->
{A1, A2, A3} = case get(random_seed) of
undefined -> seed0();
Tuple -> Tuple
end,
B1 = (A1*171) rem 30269,
B2 = (A2*172) rem 30307,
B3 = (A3*170) rem 30323,
put(random_seed, {B1,B2,B3}),
R = A1/30269 + A2/30307 + A3/30323,
R - trunc(R).

As seed commonly set using erlang:now(), and at least the third
element (milliseconds) of erlang:now() may be 0, the implementation
violates the algorithm specification.

In general: Randomness of random:uniform is broken, when a single
element of the seed contains a 0.

* How would you solve this issue?

When setting the seed via any random:seed function, 0 should be
automatically changed to 1, so erlang:now can savely be used as seed
generator.

Kind regards,

Florian Schintke
--
Florian Schintke <>, http://www.zib.de/schintke/
```