Skip to content

Loading…

Fix integer generator to generate uniform numbers #46

Closed
wants to merge 1 commit into from

2 participants

@Motiejus

?RANDOM:uniform(0, Number) is sufficient for random number generation.

This fixes random number generation case:
http://erlang.org/pipermail/erlang-questions/2012-September/069104.html

@Motiejus Motiejus Fix integer generator to generate uniform numbers
?RANDOM:uniform(0, Number) is sufficient for random number generation.
1950c8a
@kostis
Collaborator

First of all, apologies for the delay in reacting on this one.

We are not going to merge this pull request. The generation of random integers in PropEr cannot be totally random. It needs to be skewed so that it generates "several small numbers, including 0", "the same number more than once", "some numbers that are likely to be boundaries, e.g. close to byte()-end", etc.

However, you raise a valid point in your mail(*) reporting that the range you get is perhaps not the one you would have expected. We should look into this issue, but its solution is not the one this pull request proposes. (Actually, you should have expected that because if it were so simple we would not have spent the extra effort to write the generator that currently exists in PropEr's code base.)

(*) The pointer to your original mail in your pull request is the wrong one, at least now that I write this...

@kostis kostis closed this
@Motiejus

Yes, indeed I realized it when I used it. The range has to be skewed towards 0 at least. Thanks for feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 12, 2012
  1. @Motiejus

    Fix integer generator to generate uniform numbers

    Motiejus committed
    ?RANDOM:uniform(0, Number) is sufficient for random number generation.
Showing with 3 additions and 28 deletions.
  1. +3 −28 src/proper_arith.erl
View
31 src/proper_arith.erl
@@ -237,39 +237,14 @@ rand_int(Const) ->
rand_non_neg_int(Const) ->
trunc(rand_non_neg_float(Const)).
--spec bounded_rand_non_neg_int(non_neg_integer(), non_neg_integer()) ->
- non_neg_integer().
-bounded_rand_non_neg_int(Const, Lim) when is_integer(Lim), Lim >= 0 ->
- X = rand_non_neg_int(Const),
- case X > Lim of
- true -> bounded_rand_non_neg_int(Const, Lim);
- false -> X
- end.
-
-spec rand_int(integer(), integer()) -> integer().
rand_int(Low, High) when is_integer(Low), is_integer(High), Low =< High ->
Low + ?RANDOM_MOD:uniform(High - Low + 1) - 1.
-%% When the range is large, skew the distribution to be more like that of an
-%% unbounded random integer.
+%% TODO: Consider Coefficient (Size/Max_Size) for the random number
-spec smart_rand_int(non_neg_integer(), integer(), integer()) -> integer().
-smart_rand_int(Const, Low, High) ->
- case High - Low =< ?SMALL_RANGE_THRESHOLD of
- true -> rand_int(Low, High);
- false -> wide_range_rand_int(Const, Low, High)
- end.
-
--spec wide_range_rand_int(non_neg_integer(), integer(), integer()) ->
- integer().
-wide_range_rand_int(Const, Low, High) when Low >= 0 ->
- Low + bounded_rand_non_neg_int(Const, High - Low);
-wide_range_rand_int(Const, Low, High) when High =< 0 ->
- High - bounded_rand_non_neg_int(Const, High - Low);
-wide_range_rand_int(Const, Low, High) ->
- case ?RANDOM_MOD:uniform(2) of
- 1 -> smart_rand_int(Const, 0, High);
- 2 -> smart_rand_int(Const, Low, 0)
- end.
+smart_rand_int(_Const, Low, High) ->
+ rand_int(Low, High).
-spec rand_float(non_neg_integer()) -> float().
rand_float(Const) ->
Something went wrong with that request. Please try again.