aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2011-09-07 11:09:43 +0200
committerSverker Eriksson <[email protected]>2011-09-07 11:09:43 +0200
commit02b8d9b4d669ae215b1c2423fa961db1b69a487f (patch)
treef7a1b27dc3a243da40dc2e98d888e6eb245e9342 /lib
parent22dae863060e0d66fa268f6d1cd4d6f084b850ab (diff)
downloadotp-02b8d9b4d669ae215b1c2423fa961db1b69a487f.tar.gz
otp-02b8d9b4d669ae215b1c2423fa961db1b69a487f.tar.bz2
otp-02b8d9b4d669ae215b1c2423fa961db1b69a487f.zip
[crypto] Fix rand_uniform for negative values
Also let it throw badarg if 'Hi' is not larger than 'Lo'.
Diffstat (limited to 'lib')
-rw-r--r--lib/crypto/doc/src/crypto.xml2
-rw-r--r--lib/crypto/src/crypto.erl11
-rw-r--r--lib/crypto/test/crypto_SUITE.erl11
3 files changed, 20 insertions, 4 deletions
diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml
index 179ba4498c..96c4a072e1 100644
--- a/lib/crypto/doc/src/crypto.xml
+++ b/lib/crypto/doc/src/crypto.xml
@@ -744,7 +744,7 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]>
<p>Generate a random number <c><![CDATA[N, Lo =< N < Hi.]]></c> Uses the
<c>crypto</c> library pseudo-random number generator. The
arguments (and result) can be either erlang integers or binary
- multi-precision integers.</p>
+ multi-precision integers. <c>Hi</c> must be larger than <c>Lo</c>.</p>
</desc>
</func>
<func>
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index c35dfcebab..c3e13d6b91 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -415,6 +415,13 @@ rand_uniform(From,To) when is_binary(From), is_binary(To) ->
Whatever
end;
rand_uniform(From,To) when is_integer(From),is_integer(To) ->
+ if From < 0 ->
+ rand_uniform_pos(0, To - From) + From;
+ true ->
+ rand_uniform_pos(From, To)
+ end.
+
+rand_uniform_pos(From,To) when From < To ->
BinFrom = mpint(From),
BinTo = mpint(To),
case rand_uniform(BinFrom, BinTo) of
@@ -422,7 +429,9 @@ rand_uniform(From,To) when is_integer(From),is_integer(To) ->
erlint(Result);
Other ->
Other
- end.
+ end;
+rand_uniform_pos(_,_) ->
+ error(badarg).
rand_uniform_nif(_From,_To) -> ?nif_stub.
diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl
index 283aadb6ea..8d2f42469b 100644
--- a/lib/crypto/test/crypto_SUITE.erl
+++ b/lib/crypto/test/crypto_SUITE.erl
@@ -878,10 +878,17 @@ rand_uniform_aux_test(0) ->
rand_uniform_aux_test(N) ->
?line L = N*1000,
?line H = N*100000+1,
+ ?line crypto_rand_uniform(L, H),
+ ?line crypto_rand_uniform(-L, L),
+ ?line crypto_rand_uniform(-H, -L),
+ ?line crypto_rand_uniform(-H, L),
+ ?line rand_uniform_aux_test(N-1).
+
+crypto_rand_uniform(L,H) ->
?line R1 = crypto:rand_uniform(L, H),
?line t(R1 >= L),
- ?line t(R1 < H),
- ?line rand_uniform_aux_test(N-1).
+ ?line t(R1 < H).
+
%%
%%