Skip to content

Commit e85e008

Browse files
authored
Fix sample with wide integer types (#873)
As observed in issue 872, an unordered sample without replacement with a type 64 bits or wider (notably excluding `Int64`, at least on a 64-bit system) hits a `MethodError` in `samplepair`, which had been restricted to `Int` inputs. Relaxing this restriction and adjusting the `samplepair` implementation accordingly allows these cases to succeed.
1 parent 82190d1 commit e85e008

File tree

3 files changed

+33
-6
lines changed

3 files changed

+33
-6
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "StatsBase"
22
uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
33
authors = ["JuliaStats"]
4-
version = "0.34.0"
4+
version = "0.34.1"
55

66
[deps]
77
DataAPI = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"

src/sampling.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,12 @@ Draw a pair of distinct integers between 1 and `n` without replacement.
105105
Optionally specify a random number generator `rng` as the first argument
106106
(defaults to `Random.GLOBAL_RNG`).
107107
"""
108-
function samplepair(rng::AbstractRNG, n::Int)
109-
i1 = rand(rng, 1:n)
110-
i2 = rand(rng, 1:n-1)
108+
function samplepair(rng::AbstractRNG, n::Integer)
109+
i1 = rand(rng, one(n):n)
110+
i2 = rand(rng, one(n):(n - one(n)))
111111
return (i1, ifelse(i2 == i1, n, i2))
112112
end
113-
samplepair(n::Int) = samplepair(Random.GLOBAL_RNG, n)
113+
samplepair(n::Integer) = samplepair(Random.GLOBAL_RNG, n)
114114

115115
"""
116116
samplepair([rng], a)

test/sampling.jl

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ test_rng_use(sample, 1:10, 10)
9191

9292
@test samplepair(rng, [3, 4, 2, 6, 8]) === (3, 8)
9393
@test samplepair(rng, [1, 2]) === (1, 2)
94+
95+
onetwo = samplepair(rng, UInt128(2))
96+
@test extrema(onetwo) == (1, 2)
97+
@test eltype(onetwo) === UInt128
9498
end
9599

96100
test_rng_use(samplepair, 1000)
@@ -265,4 +269,27 @@ test_same(replace=false, ordered=false)
265269
# This corner case should succeed
266270
f(view(x, 2:4), view(x, 5:6))
267271
end
268-
end
272+
end
273+
274+
@testset "issue #872" begin
275+
for T in [Int8, Int16, Int32, Int64, Int128, BigInt], f in [identity, unsigned]
276+
T == BigInt && f == unsigned && continue
277+
T = f(T)
278+
# The type of the second argument should not affect the return type
279+
let samp = sample(T(1):T(10), T(2); replace=false, ordered=false)
280+
@test all(x -> x isa T, samp)
281+
@test all(x -> T(1) <= x <= T(10), samp)
282+
@test length(samp) == 2
283+
end
284+
let samp = sample(T(1):T(10), 2; replace=false, ordered=false)
285+
@test all(x -> x isa T, samp)
286+
@test all(x -> T(1) <= x <= T(10), samp)
287+
@test length(samp) == 2
288+
end
289+
let samp = sample(1:10, T(2); replace=false, ordered=false)
290+
@test all(x -> x isa Int, samp)
291+
@test all(x -> 1 <= x <= 10, samp)
292+
@test length(samp) == 2
293+
end
294+
end
295+
end

0 commit comments

Comments
 (0)