[erlang-bugs] Bug in module random (stdlib-1.16.5, R13B04)

Raimo Niskanen raimo+erlang-bugs@REDACTED
Mon Jun 14 14:39:01 CEST 2010


Thank you for reporting this problem. Your suggested fix to replace
0 with 1 in the seed also seems as the least bad workaround.

I am amazed nobody reported this before.

It will be fixed or at least documented in earliest feasible release
(unfortunately not R14A).



On Fri, Jun 11, 2010 at 05:26:13PM +0200, Florian Schintke wrote:
> 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/
> 
> ________________________________________________________________
> erlang-bugs (at) erlang.org mailing list.
> See http://www.erlang.org/faq.html
> To unsubscribe; mailto:erlang-bugs-unsubscribe@REDACTED

-- 

/ Raimo Niskanen, Erlang/OTP, Ericsson AB


More information about the erlang-bugs mailing list