[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