Bug in module random (stdlib-1.16.5, R13B04)

Florian Schintke schintke@REDACTED
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

* Please provide any additional information below.

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 <schintke@REDACTED>, http://www.zib.de/schintke/


More information about the erlang-bugs mailing list