diff --git a/base/random.jl b/base/random.jl index 04f3a9317f85c1..e21be48b3f098a 100644 --- a/base/random.jl +++ b/base/random.jl @@ -176,31 +176,23 @@ for (T, U) in [(Uint8, Uint32), (Uint16, Uint32), @eval randintgen(k::$T) = k<1 ? error("range must be non-empty") : RandIntGen($T, convert($U, k)) end +function rand_lessthan{U}(u::U) # TODO: inline + while true + x = rand(U) + x <= u && return x + end +end + # this function uses 32 bit entropy for small ranges of length <= typemax(Uint32) + 1 # RandIntGen is responsible for providing the right value of k -function rand{T<:Union(Uint64, Int64)}(g::RandIntGen{T,Uint64}) - local x::Uint64 - if (g.k - 1) >> 32 == 0 - x = rand(Uint32) - while x > g.u - x = rand(Uint32) - end - else - x = rand(Uint64) - while x > g.u - x = rand(Uint64) - end - end +function rand{T}(g::RandIntGen{T,Uint64}) + x = (g.k - 1) >> 32 == 0 ? + uint64(rand_lessthan(uint32(g.u))) : + rand_lessthan(g.u) return convert(T, 1 + x % g.k) end -function rand{T<:Integer, U<:Unsigned}(g::RandIntGen{T,U}) - x = rand(U) - while x > g.u - x = rand(U) - end - convert(T, 1 + x % g.k) -end +rand{T}(g::RandIntGen{T}) = convert(T, 1 + rand_lessthan(g.u) % g.k) ## Randomly draw a sample from an AbstractArray r