Skip to content

Instantly share code, notes, and snippets.

@mschauer
Created January 28, 2014 15:08
Show Gist options
  • Save mschauer/8669275 to your computer and use it in GitHub Desktop.
Save mschauer/8669275 to your computer and use it in GitHub Desktop.
import Base.Random.rand
immutable RandIntGen2{T<:Integer, U<:Unsigned}
a::T # first element of the range
k::U # range length
u::U # maximum multiple of k within the domain of U
RandIntGen2(a::T, k::U) = new(a, k, div(typemax(U),k)*k)
RandIntGen2(a::Uint64, k::Uint64) = new(a, k, div(( k >> 32 != 0)*0xFFFFFFFF00000000 + 0x00000000FFFFFFFF ,k)*k )
RandIntGen2(a::Int64, k::Int64) = new(a, k, div(( k >> 32 != 0)*0xFFFFFFFF00000000 + 0x00000000FFFFFFFF ,k)*k )
end
immutable RandIntGen1{T<:Integer, U<:Unsigned}
a::T # first element of the range
k::U # range length
u::U # maximum multiple of k within the domain of U
RandIntGen1(a::T, k::U) = new(a, k, div(typemax(U),k)*k)
end
function rand{T<:Integer,U<:Unsigned}(g::RandIntGen1{T,U})
x = rand(U)
while x >= g.u
x = rand(U)
end
convert(T, g.a + rem(x, g.k))
end
function rand{T}(g::RandIntGen2{T,Uint64})
local x::Uint64
if g.k >> 32 == 0
x = convert(Uint64,rand(Uint32))
while x >= g.u
x = convert(Uint64,rand(Uint32))
end
else
x = rand(Uint64)
while x >= g.u
x = rand(Uint64)
end
end
return convert(T, g.a + rem(x, g.k))
end
# print elapsed time, return expression value
macro timen(N, ex)
quote
local b0 = Base.gc_bytes()
local t0 = time_ns()
for i in 1:$N
$(esc(ex))
end
local t1 = time_ns()
local b1 = Base.gc_bytes()
println("elapsed time: ", (t1-t0)/1e9, " seconds (", b1-b0, " bytes allocated)")
end
end
rand(RandIntGen1{Uint, Uint}(0x0000000000000000,0x0000010000000000))
rand(RandIntGen2{Uint, Uint}(0x0000000000000000,0x0000010000000000))
@timen 10^8 rand(RandIntGen1{Uint, Uint}(0x0000000000000000,0x0000010000000000))
@timen 10^8 rand(RandIntGen2{Uint, Uint}(0x0000000000000000,0x0000010000000000))
@timen 10^8 rand(RandIntGen1{Uint, Uint}(0x0000000000000000,0x0000000010001000))
@timen 10^8 rand(RandIntGen2{Uint, Uint}(0x0000000000000000,0x0000000010001000))
srand(123); println(rand(RandIntGen2{Uint32, Uint32}(0x00000000,0x10001000)))
srand(123); println(rand(RandIntGen2{Uint64, Uint64}(0x0000000000000000,0x0000000010001000)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment