Hello again. I'm trying to make a package that fetches random numbers from an API. I can get them as UInt8 and UInt16s. I use bit shifting to get UInt32,64,128 and some random bools for Int8,16,32,64,128. However, I'm stuck on Floats. It would get great if I could just tell Julia to take an Int64 and then treat the same pointer as a Float64 ... but my google-fu has not revealed a way to do so.
Any suggestions?
Like this (using reinterpret)?
julia> x = 0x400921fb54442d18;
julia> reinterpret(Float64, x)
3.141592653589793
That looks great! Thanks
Looks like I just need to find a way to set the exponent bits now...
Probably easier if I do that with the UInt64
You might be looking for frexp
frexp.(reinterpret.(Float64, rand(UInt64, 20))) looks promising, but I'm thinking try bitwise operations first
I think as long as I set the start to 0b001111111100 then I should get a Float in [0, 1]
You might want to think about what kind of distribution you want. Assuming your random sources are uniformly distributed you're about to construct a uniform distribution on the representable floating point numbers in [0, 1], which is rather different from a uniform distribution on the real numbers in [0, 1].
The target here is a uniform distribution on [0, 1]
Since the UInt64should be uniform, I interpret that as each bit being fairly random (in the "fair coin" sense of fair).
Turns out looking at the IEE 754 spec was helpful, who would have thought :stuck_out_tongue:. Result looks good
image.png
If you want (0,1) instead of [0,1], an easy way is to mask the random UInt64 it into [1,2) and then subtract prevfloat(1.0).
That's what I'm doing actually :smile:
Unfortunately, it turns out that Random deals with Float64 in a different way ... which means I'm currently just getting error :frown:
ERROR: StackOverflowError:
Stacktrace:
[1] _rand52(r::ANUQRNG, #unused#::Type{Float64})
@ Random /home/abuild/rpmbuild/BUILD/julia-1.6.0/usr/share/julia/stdlib/v1.6/Random/src/generation.jl:117
[2] rand(r::ANUQRNG, #unused#::Random.SamplerTrivial{Random.UInt52Raw{UInt64}, UInt64})
@ Random /home/abuild/rpmbuild/BUILD/julia-1.6.0/usr/share/julia/stdlib/v1.6/Random/src/generation.jl:114
[3] rand(rng::ANUQRNG, X::Random.UInt52Raw{UInt64})
@ Random /home/abuild/rpmbuild/BUILD/julia-1.6.0/usr/share/julia/stdlib/v1.6/Random/src/Random.jl:253
[4] rand(r::ANUQRNG, #unused#::Random.SamplerTrivial{Random.UInt52{UInt64}, UInt64})
@ Random /home/abuild/rpmbuild/BUILD/julia-1.6.0/usr/share/julia/stdlib/v1.6/Random/src/generation.jl:125
[5] rand(rng::ANUQRNG, X::Random.UInt52{UInt64})
@ Random /home/abuild/rpmbuild/BUILD/julia-1.6.0/usr/share/julia/stdlib/v1.6/Random/src/Random.jl:253
[6] rand(r::ANUQRNG, #unused#::Random.SamplerTrivial{Random.CloseOpen12{Float64}, Float64})
@ Random /home/abuild/rpmbuild/BUILD/julia-1.6.0/usr/share/julia/stdlib/v1.6/Random/src/generation.jl:32
[7] rand(rng::ANUQRNG, X::Random.CloseOpen12{Float64})
@ Random /home/abuild/rpmbuild/BUILD/julia-1.6.0/usr/share/julia/stdlib/v1.6/Random/src/Random.jl:253
--- the last 7 lines are repeated 11425 more times ---
[79983] _rand52(r::ANUQRNG, #unused#::Type{Float64})
@ Random /home/abuild/rpmbuild/BUILD/julia-1.6.0/usr/share/julia/stdlib/v1.6/Random/src/generation.jl:117
julia> @inline setbits(x, y, m) = (x & m) | y
setbits (generic function with 1 method)
julia> @inline floatbitmask(x, ::Type{Float64}) = reinterpret(Float64, setbits(reinterpret(UInt64, x), 0x3ff0000000000000, 0x000fffffffffffff))
floatbitmask (generic function with 1 method)
julia> @inline floatbitmask(x, ::Type{Float32}) = reinterpret(Float32, setbits(reinterpret(UInt32, x), 0x3f800000, 0x007fffff))
floatbitmask (generic function with 2 methods)
julia> floatbitmask(rand(UInt64), Float64) - prevfloat(1.0)
0.05111789230783048
julia> floatbitmask(rand(UInt64), Float64) - prevfloat(1.0)
0.20961601722925594
julia> floatbitmask(rand(UInt64), Float64) - prevfloat(1.0)
0.9792547222862796
julia> floatbitmask(rand(UInt64), Float64) - prevfloat(1.0)
0.1771319766794791
julia> floatbitmask(rand(UInt64), Float64) - prevfloat(1.0)
0.7201901350024212
julia> floatbitmask(typemin(UInt64), Float64) - prevfloat(1.0)
1.1102230246251565e-16
julia> floatbitmask(typemax(UInt64), Float64) - prevfloat(1.0)
0.9999999999999999
Not sure what you're trying to do that resulted in that error?
I'm directly generating random Float64s and apparently Random isn't built to accept that easily...
What does directly generating them mean?
What're you calling?
Well, for all the Int types (UInt8, UInt16, ..., Int64, Int128`) I'm defining a function
function rand!(r::ANUQRNG, A::Array{$T}, sp::Random.SamplerType{$T})
but having the same for floats doesn't allow for random floats to be generated.
Ah! Found what I need:
function rand!(r::ANUQRNG, A::Array{Float64}, sp::Random.SamplerTrivial{Random.CloseOpen01{Float64}, Float64})
Last updated: Nov 27 2025 at 04:44 UTC