From 5a496c0c10419ab5e2890a21d233f0d57462ceaa Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Wed, 4 Sep 2019 14:03:43 -0400 Subject: [PATCH] bugfixes in Libc.rand for Windows (#32895) --- base/libc.jl | 12 +++++++++--- test/misc.jl | 7 +++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/base/libc.jl b/base/libc.jl index 9fd67460ac019..3ad15e9c2c2fe 100644 --- a/base/libc.jl +++ b/base/libc.jl @@ -382,9 +382,15 @@ Interface to the C `rand()` function. If `T` is provided, generate a value of ty by composing two calls to `rand()`. `T` can be `UInt32` or `Float64`. """ rand() = ccall(:rand, Cint, ()) -# RAND_MAX at least 2^15-1 in theory, but we assume 2^16-1 (in practice, it's 2^31-1) -rand(::Type{UInt32}) = ((rand() % UInt32) << 16) ⊻ (rand() % UInt32) -rand(::Type{Float64}) = rand(UInt32) / 2^32 +@static if Sys.iswindows() + # Windows RAND_MAX is 2^15-1 + rand(::Type{UInt32}) = ((rand() % UInt32) << 17) ⊻ ((rand() % UInt32) << 8) ⊻ (rand() % UInt32) +else + # RAND_MAX is at least 2^15-1 in theory, but we assume 2^16-1 + # on non-Windows systems (in practice, it's 2^31-1) + rand(::Type{UInt32}) = ((rand() % UInt32) << 16) ⊻ (rand() % UInt32) +end +rand(::Type{Float64}) = rand(UInt32) * 2.0^-32 """ srand([seed]) diff --git a/test/misc.jl b/test/misc.jl index 68142072337b9..fc1cc309adc0f 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -745,6 +745,13 @@ end @test sort([a, b]) == [b, a] end +@testset "Libc.rand" begin + low, high = extrema(Libc.rand(Float64) for i=1:10^4) + # these fail with probability 2^(-10^4) ≈ 5e-3011 + @test 0 ≤ low < 0.5 + @test 0.5 < high < 1 +end + # Pointer 0-arg constructor @test Ptr{Cvoid}() == C_NULL