Reputation: 1757
The docs say rand
draws iid uniformly distributed values in the half-open unit interval [0,1) which includes zero but is rand ever throwing a zero?
Upvotes: 3
Views: 147
Reputation: 1757
Yes, it is possible for rand()
to return zero and rand()
does not return one.
Software should be designed to work whether or not iszero(rand())
. And it is
good practice to provide an appropriate test case. How often does a computer that is continuously generating rand()
yield zero? Using very rough estimates: about every six weeks.
Sometimes it may be more appropriate to sample from (0.0, 1.0], omitting zero while permitting one. Here is one way to do that.
zero_as_one(x::T) where {T<:AbstractFloat} =
ifelse(iszero(x), one(T), x)
rand1(::Type{T}) where {T<:AbstractFloat} =
zero_as_one(rand(T))
function rand1(::Type{T}, n::I) where {T<:AbstractFloat, I<:Integer}
n < 1 && throw(ArgumentError("n must be >= 1"))
n === one(I) && return rand1(T)
return map(zero_as_one, rand(T, n))
end
Here is a way to sample from (0.0, 1.0), omitting both zero and one.
openrand() = openrand(Float64)
openrand(::Type{T}) where {T<:AbstractFloat} =
let result = rand(T)
while iszero(result)
result = openrand(T)
end
result
end
function openrand(::Type{T}, n::I) where {T<:AbstractFloat, I<:Integer}
n < 1 && throw(ArgumentError("n must be >= 1"))
n === one(I) && return openrand(T)
result = Vector{T}(undef, n)
for i in 1:n
result[i] = openrand(T)
end
return result
end
In addition to Julia, C, C++, Fortran, Perl, Python, Ruby, and Spreadsheets also use the interval [0.0, 1.0) for uniform random sampling. Matlab and R use (0.0, 1.0). Mathematica uses [0.0, 1.0].
the original thread on discourse
Upvotes: 3