• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JuliaLang / julia / #37919

29 Sep 2024 09:41AM UTC coverage: 86.232% (-0.3%) from 86.484%
#37919

push

local

web-flow
fix rawbigints OOB issues (#55917)

Fixes issues introduced in #50691 and found in #55906:
* use `@inbounds` and `@boundscheck` macros in rawbigints, for catching
OOB with `--check-bounds=yes`
* fix OOB in `truncate`

12 of 13 new or added lines in 1 file covered. (92.31%)

1287 existing lines in 41 files now uncovered.

77245 of 89578 relevant lines covered (86.23%)

15686161.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.14
/stdlib/Random/src/Random.jl
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2

3
"""
4
    Random
5

6
Support for generating random numbers. Provides [`rand`](@ref), [`randn`](@ref),
7
[`AbstractRNG`](@ref), [`Xoshiro`](@ref), [`MersenneTwister`](@ref), and [`RandomDevice`](@ref).
8
"""
9
module Random
10

11
include("DSFMT.jl")
12

13
using .DSFMT
14
using Base.GMP.MPZ
15
using Base.GMP: Limb
16
import SHA
17

18
using Base: BitInteger, BitInteger_types, BitUnsigned, require_one_based_indexing
19
import Base: copymutable, copy, copy!, ==, hash, convert,
20
             rand, randn, show
21

22
export rand!, randn!,
23
       randexp, randexp!,
24
       bitrand,
25
       randstring,
26
       randsubseq, randsubseq!,
27
       shuffle, shuffle!,
28
       randperm, randperm!,
29
       randcycle, randcycle!,
30
       AbstractRNG, MersenneTwister, RandomDevice, TaskLocalRNG, Xoshiro
31

32
public seed!, default_rng, Sampler, SamplerType, SamplerTrivial, SamplerSimple
33

34
## general definitions
35

36
"""
37
    AbstractRNG
38

39
Supertype for random number generators such as [`MersenneTwister`](@ref) and [`RandomDevice`](@ref).
40
"""
41
abstract type AbstractRNG end
42

UNCOV
43
Base.broadcastable(x::AbstractRNG) = Ref(x)
×
44

45
gentype(::Type{X}) where {X} = eltype(X)
2,137,924✔
46
gentype(x) = gentype(typeof(x))
1,006,565✔
47

48

49
### integers
50

51
# we define types which encode the generation of a specific number of bits
52
# the "raw" version means that the unused bits are not zeroed
53

54
abstract type UniformBits{T<:BitInteger} end
55

56
struct UInt10{T}    <: UniformBits{T} end
57
struct UInt10Raw{T} <: UniformBits{T} end
58

59
struct UInt23{T}    <: UniformBits{T} end
60
struct UInt23Raw{T} <: UniformBits{T} end
61

62
struct UInt52{T}    <: UniformBits{T} end
11,089,050✔
63
struct UInt52Raw{T} <: UniformBits{T} end
262,384✔
64

65
struct UInt104{T}    <: UniformBits{T} end
66
struct UInt104Raw{T} <: UniformBits{T} end
67

68
struct UInt2x52{T}    <: UniformBits{T} end
69
struct UInt2x52Raw{T} <: UniformBits{T} end
947✔
70

UNCOV
71
uint_sup(::Type{<:Union{UInt10,UInt10Raw}}) = UInt16
×
UNCOV
72
uint_sup(::Type{<:Union{UInt23,UInt23Raw}}) = UInt32
×
73
uint_sup(::Type{<:Union{UInt52,UInt52Raw}}) = UInt64
11,296,155✔
UNCOV
74
uint_sup(::Type{<:Union{UInt104,UInt104Raw}}) = UInt128
×
75
uint_sup(::Type{<:Union{UInt2x52,UInt2x52Raw}}) = UInt128
947✔
76

77
for UI = (:UInt10, :UInt10Raw, :UInt23, :UInt23Raw, :UInt52, :UInt52Raw,
78
          :UInt104, :UInt104Raw, :UInt2x52, :UInt2x52Raw)
79
    @eval begin
80
        $UI(::Type{T}=uint_sup($UI)) where {T} = $UI{T}()
22,500,609✔
81
        # useful for defining rand generically:
82
        uint_default(::$UI) = $UI{uint_sup($UI)}()
74,437✔
83
    end
84
end
85

86
gentype(::Type{<:UniformBits{T}}) where {T} = T
11,371,539✔
87

88
### floats
89

90
abstract type FloatInterval{T<:AbstractFloat} end
91

92
struct CloseOpen01{T<:AbstractFloat} <: FloatInterval{T} end # interval [0,1)
47,608,819✔
93
struct CloseOpen12{T<:AbstractFloat} <: FloatInterval{T} end # interval [1,2)
19,182✔
94

95
const FloatInterval_64 = FloatInterval{Float64}
96
const CloseOpen01_64   = CloseOpen01{Float64}
97
const CloseOpen12_64   = CloseOpen12{Float64}
98

99
CloseOpen01(::Type{T}=Float64) where {T<:AbstractFloat} = CloseOpen01{T}()
46,122,075✔
100
CloseOpen12(::Type{T}=Float64) where {T<:AbstractFloat} = CloseOpen12{T}()
38,342✔
101

102
gentype(::Type{<:FloatInterval{T}}) where {T<:AbstractFloat} = T
44,644,103✔
103

104
const BitFloatType = Union{Type{Float16},Type{Float32},Type{Float64}}
105

106
### Sampler
107

108
abstract type Sampler{E} end
109

UNCOV
110
gentype(::Type{<:Sampler{E}}) where {E} = E
×
111

112
# temporarily for BaseBenchmarks
113
RangeGenerator(x) = Sampler(default_rng(), x)
×
114

115
# In some cases, when only 1 random value is to be generated,
116
# the optimal sampler can be different than if multiple values
117
# have to be generated. Hence a `Repetition` parameter is used
118
# to choose the best one depending on the need.
119
const Repetition = Union{Val{1},Val{Inf}}
120

121
# these default fall-back for all RNGs would be nice,
122
# but generate difficult-to-solve ambiguities
123
# Sampler(::AbstractRNG, X, ::Val{Inf}) = Sampler(X)
124
# Sampler(::AbstractRNG, ::Type{X}, ::Val{Inf}) where {X} = Sampler(X)
125

126
"""
127
    Sampler(rng, x, repetition = Val(Inf))
128

129
Return a sampler object that can be used to generate random values from `rng` for `x`.
130

131
When `sp = Sampler(rng, x, repetition)`, `rand(rng, sp)` will be used to draw random values,
132
and should be defined accordingly.
133

134
`repetition` can be `Val(1)` or `Val(Inf)`, and should be used as a suggestion for deciding
135
the amount of precomputation, if applicable.
136

137
[`Random.SamplerType`](@ref) and [`Random.SamplerTrivial`](@ref) are default fallbacks for
138
*types* and *values*, respectively. [`Random.SamplerSimple`](@ref) can be used to store
139
pre-computed values without defining extra types for only this purpose.
140
"""
141
Sampler(rng::AbstractRNG, x, r::Repetition=Val(Inf)) = Sampler(typeof(rng), x, r)
16,923,348✔
142
Sampler(rng::AbstractRNG, ::Type{X}, r::Repetition=Val(Inf)) where {X} =
120,383,659✔
143
    Sampler(typeof(rng), X, r)
144

145
# this method is necessary to prevent rand(rng::AbstractRNG, X) from
146
# recursively constructing nested Sampler types.
147
Sampler(T::Type{<:AbstractRNG}, sp::Sampler, r::Repetition) =
1✔
148
    throw(MethodError(Sampler, (T, sp, r)))
149

150
# default shortcut for the general case
UNCOV
151
Sampler(::Type{RNG}, X) where {RNG<:AbstractRNG} = Sampler(RNG, X, Val(Inf))
×
UNCOV
152
Sampler(::Type{RNG}, ::Type{X}) where {RNG<:AbstractRNG,X} = Sampler(RNG, X, Val(Inf))
×
153

154
#### pre-defined useful Sampler types
155

156
"""
157
    SamplerType{T}()
158

159
A sampler for types, containing no other information. The default fallback for `Sampler`
160
when called with types.
161
"""
162
struct SamplerType{T} <: Sampler{T} end
2,355,459✔
163

164
Sampler(::Type{<:AbstractRNG}, ::Type{T}, ::Repetition) where {T} = SamplerType{T}()
70,892,621✔
165

166
Base.getindex(::SamplerType{T}) where {T} = T
1,394,129✔
167

168
struct SamplerTrivial{T,E} <: Sampler{E}
169
    self::T
56,016,369✔
170
end
171

172
"""
173
    SamplerTrivial(x)
174

175
Create a sampler that just wraps the given value `x`. This is the default fall-back for
176
values.
177
The `eltype` of this sampler is equal to `eltype(x)`.
178

179
The recommended use case is sampling from values without precomputed data.
180
"""
181
SamplerTrivial(x::T) where {T} = SamplerTrivial{T,gentype(T)}(x)
56,016,369✔
182

183
Sampler(::Type{<:AbstractRNG}, x, ::Repetition) = SamplerTrivial(x)
56,015,638✔
184

185
Base.getindex(sp::SamplerTrivial) = sp.self
92,403✔
186

187
# simple sampler carrying data (which can be anything)
188
struct SamplerSimple{T,S,E} <: Sampler{E}
189
    self::T
1,130,630✔
190
    data::S
191
end
192

193
"""
194
    SamplerSimple(x, data)
195

196
Create a sampler that wraps the given value `x` and the `data`.
197
The `eltype` of this sampler is equal to `eltype(x)`.
198

199
The recommended use case is sampling from values with precomputed data.
200
"""
201
SamplerSimple(x::T, data::S) where {T,S} = SamplerSimple{T,S,gentype(T)}(x, data)
1,130,630✔
202

203
Base.getindex(sp::SamplerSimple) = sp.self
1,223,285✔
204

205
# simple sampler carrying a (type) tag T and data
206
struct SamplerTag{T,S,E} <: Sampler{E}
207
    data::S
208
    SamplerTag{T}(s::S) where {T,S} = new{T,S,gentype(T)}(s)
2✔
209
end
210

211

212
#### helper samplers
213

214
# TODO: make constraining constructors to enforce that those
215
# types are <: Sampler{T}
216

217
##### Adapter to generate a random value in [0, n]
218

219
struct LessThan{T<:Integer,S} <: Sampler{T}
220
    sup::T
53,407✔
221
    s::S    # the scalar specification/sampler to feed to rand
222
end
223

224
function rand(rng::AbstractRNG, sp::LessThan)
53,407✔
225
    while true
74,459✔
226
        x = rand(rng, sp.s)
74,459✔
227
        x <= sp.sup && return x
74,459✔
228
    end
21,052✔
229
end
230

231
struct Masked{T<:Integer,S} <: Sampler{T}
232
    mask::T
53,407✔
233
    s::S
234
end
235

236
rand(rng::AbstractRNG, sp::Masked) = rand(rng, sp.s) & sp.mask
74,459✔
237

238
##### Uniform
239

240
struct UniformT{T} <: Sampler{T} end
22✔
241

242
uniform(::Type{T}) where {T} = UniformT{T}()
22✔
243

244
rand(rng::AbstractRNG, ::UniformT{T}) where {T} = rand(rng, T)
22✔
245

246

247
### machinery for generation with Sampler
248

249
# This describes how to generate random scalars or arrays, by generating a Sampler
250
# and calling rand on it (which should be defined in "generation.jl").
251
# NOTE: this section could be moved into a separate file when more containers are supported.
252

253
#### scalars
254

255
rand(rng::AbstractRNG, X)                                           = rand(rng, Sampler(rng, X, Val(1)))
14,888,071✔
256
# this is needed to disambiguate
UNCOV
257
rand(rng::AbstractRNG, X::Dims)                                     = rand(rng, Sampler(rng, X, Val(1)))
×
258
rand(rng::AbstractRNG=default_rng(), ::Type{X}=Float64) where {X}   = rand(rng, Sampler(rng, X, Val(1)))::X
156,366,526✔
259

260
rand(X)                   = rand(default_rng(), X)
3,514,988✔
261
rand(::Type{X}) where {X} = rand(default_rng(), X)
2,957,149✔
262

263
#### arrays
264

265
rand!(A::AbstractArray{T}, X) where {T}             = rand!(default_rng(), A, X)
43✔
266
rand!(A::AbstractArray{T}, ::Type{X}=T) where {T,X} = rand!(default_rng(), A, X)
277,360✔
267

268
rand!(rng::AbstractRNG, A::AbstractArray{T}, X) where {T}             = rand!(rng, A, Sampler(rng, X))
3,049,611✔
269
rand!(rng::AbstractRNG, A::AbstractArray{T}, ::Type{X}=T) where {T,X} = rand!(rng, A, Sampler(rng, X))
5,067,719✔
270

271
function rand!(rng::AbstractRNG, A::AbstractArray{T}, sp::Sampler) where T
306✔
272
    for i in eachindex(A)
1,016,008✔
273
        @inbounds A[i] = rand(rng, sp)
4,795,152✔
274
    end
8,570,648✔
275
    A
1,015,924✔
276
end
277

278
rand(r::AbstractRNG, dims::Integer...) = rand(r, Float64, Dims(dims))
914✔
279
rand(                dims::Integer...) = rand(Float64, Dims(dims))
19,006✔
280

281
rand(r::AbstractRNG, X, dims::Dims)  = rand!(r, Array{gentype(X)}(undef, dims), X)
3,012,721✔
282
rand(                X, dims::Dims)  = rand(default_rng(), X, dims)
3,012,721✔
283

UNCOV
284
rand(r::AbstractRNG, X, d::Integer, dims::Integer...) = rand(r, X, Dims((d, dims...)))
×
285
rand(                X, d::Integer, dims::Integer...) = rand(X, Dims((d, dims...)))
3,012,709✔
286
# note: the above methods would trigger an ambiguity warning if d was not separated out:
287
# rand(r, ()) would match both this method and rand(r, dims::Dims)
288
# moreover, a call like rand(r, NotImplementedType()) would be an infinite loop
289

290
rand(r::AbstractRNG, ::Type{X}, dims::Dims) where {X} = rand!(r, Array{X}(undef, dims), X)
1,680,377✔
291
rand(                ::Type{X}, dims::Dims) where {X} = rand(default_rng(), X, dims)
1,670,087✔
292

293
rand(r::AbstractRNG, ::Type{X}, d::Integer, dims::Integer...) where {X} = rand(r, X, Dims((d, dims...)))
9,376✔
294
rand(                ::Type{X}, d::Integer, dims::Integer...) where {X} = rand(X, Dims((d, dims...)))
1,650,908✔
295

296
# SamplerUnion(X, Y, ...}) == Union{SamplerType{X}, SamplerType{Y}, ...}
297
SamplerUnion(U...) = Union{Any[SamplerType{T} for T in U]...}
×
298
const SamplerBoolBitInteger = SamplerUnion(Bool, BitInteger_types...)
299

300

301
include("Xoshiro.jl")
302
include("RNGs.jl")
303
include("generation.jl")
304
include("normal.jl")
305
include("misc.jl")
306
include("XoshiroSimd.jl")
307

308
## rand & rand! & seed! docstrings
309

310
"""
311
    rand([rng=default_rng()], [S], [dims...])
312

313
Pick a random element or array of random elements from the set of values specified by `S`;
314
`S` can be
315

316
* an indexable collection (for example `1:9` or `('x', "y", :z)`)
317

318
* an `AbstractDict` or `AbstractSet` object
319

320
* a string (considered as a collection of characters), or
321

322
* a type from the list below, corresponding to the specified set of values
323

324
  + concrete integer types sample from `typemin(S):typemax(S)` (excepting [`BigInt`](@ref) which is not supported)
325

326
  + concrete floating point types sample from `[0, 1)`
327

328
  + concrete complex types `Complex{T}` if `T` is a sampleable type take their real and imaginary components
329
    independently from the set of values corresponding to `T`, but are not supported if `T` is not sampleable.
330

331
  + all `<:AbstractChar` types sample from the set of valid Unicode scalars
332

333
  + a user-defined type and set of values; for implementation guidance please see [Hooking into the `Random` API](@ref rand-api-hook)
334

335
  + a tuple type of known size and where each parameter of `S` is itself a sampleable type; return a value of type `S`.
336
    Note that tuple types such as `Tuple{Vararg{T}}` (unknown size) and `Tuple{1:2}` (parameterized with a value) are not supported
337

338
  + a `Pair` type, e.g. `Pair{X, Y}` such that `rand` is defined for `X` and `Y`,
339
    in which case random pairs are produced.
340

341

342
`S` defaults to [`Float64`](@ref).
343
When only one argument is passed besides the optional `rng` and is a `Tuple`, it is interpreted
344
as a collection of values (`S`) and not as `dims`.
345

346

347
See also [`randn`](@ref) for normally distributed numbers, and [`rand!`](@ref) and [`randn!`](@ref) for the in-place equivalents.
348

349
!!! compat "Julia 1.1"
350
    Support for `S` as a tuple requires at least Julia 1.1.
351

352
!!! compat "Julia 1.11"
353
    Support for `S` as a `Tuple` type requires at least Julia 1.11.
354

355
# Examples
356
```julia-repl
357
julia> rand(Int, 2)
358
2-element Array{Int64,1}:
359
 1339893410598768192
360
 1575814717733606317
361

362
julia> using Random
363

364
julia> rand(Xoshiro(0), Dict(1=>2, 3=>4))
365
3 => 4
366

367
julia> rand((2, 3))
368
3
369

370
julia> rand(Float64, (2, 3))
371
2×3 Array{Float64,2}:
372
 0.999717  0.0143835  0.540787
373
 0.696556  0.783855   0.938235
374
```
375

376
!!! note
377
    The complexity of `rand(rng, s::Union{AbstractDict,AbstractSet})`
378
    is linear in the length of `s`, unless an optimized method with
379
    constant complexity is available, which is the case for `Dict`,
380
    `Set` and dense `BitSet`s. For more than a few calls, use `rand(rng,
381
    collect(s))` instead, or either `rand(rng, Dict(s))` or `rand(rng,
382
    Set(s))` as appropriate.
383
"""
384
rand
385

386
"""
387
    rand!([rng=default_rng()], A, [S=eltype(A)])
388

389
Populate the array `A` with random values. If `S` is specified
390
(`S` can be a type or a collection, cf. [`rand`](@ref) for details),
391
the values are picked randomly from `S`.
392
This is equivalent to `copyto!(A, rand(rng, S, size(A)))`
393
but without allocating a new array.
394

395
# Examples
396
```jldoctest
397
julia> rand!(Xoshiro(123), zeros(5))
398
5-element Vector{Float64}:
399
 0.521213795535383
400
 0.5868067574533484
401
 0.8908786980927811
402
 0.19090669902576285
403
 0.5256623915420473
404
```
405
"""
406
rand!
407

408
"""
409
    seed!([rng=default_rng()], seed) -> rng
410
    seed!([rng=default_rng()]) -> rng
411

412
Reseed the random number generator: `rng` will give a reproducible
413
sequence of numbers if and only if a `seed` is provided. Some RNGs
414
don't accept a seed, like `RandomDevice`.
415
After the call to `seed!`, `rng` is equivalent to a newly created
416
object initialized with the same seed.
417
The types of accepted seeds depend on the type of `rng`, but in general,
418
integer seeds should work.
419

420
If `rng` is not specified, it defaults to seeding the state of the
421
shared task-local generator.
422

423
# Examples
424
```julia-repl
425
julia> Random.seed!(1234);
426

427
julia> x1 = rand(2)
428
2-element Vector{Float64}:
429
 0.32597672886359486
430
 0.5490511363155669
431

432
julia> Random.seed!(1234);
433

434
julia> x2 = rand(2)
435
2-element Vector{Float64}:
436
 0.32597672886359486
437
 0.5490511363155669
438

439
julia> x1 == x2
440
true
441

442
julia> rng = Xoshiro(1234); rand(rng, 2) == x1
443
true
444

445
julia> Xoshiro(1) == Random.seed!(rng, 1)
446
true
447

448
julia> rand(Random.seed!(rng), Bool) # not reproducible
449
true
450

451
julia> rand(Random.seed!(rng), Bool) # not reproducible either
452
false
453

454
julia> rand(Xoshiro(), Bool) # not reproducible either
455
true
456
```
457
"""
458
seed!(rng::AbstractRNG) = seed!(rng, nothing)
224✔
459
#=
460
We have this generic definition instead of the alternative option
461
`seed!(rng::AbstractRNG, ::Nothing) = seed!(rng)`
462
because it would lead too easily to ambiguities, e.g. when we define `seed!(::Xoshiro, seed)`.
463
=#
464

465
end # module
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc