Skip to content

Commit

Permalink
Cover binomial cases for large K (BigInt) (#48073)
Browse files Browse the repository at this point in the history
* Cover binomial cases for large K (BigInt)

Co-authored-by: Sebastian Stock <42280794+sostock@users.noreply.github.com>
  • Loading branch information
originalsouth and sostock committed Feb 28, 2023
1 parent a23b29c commit 832a67c
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 2 deletions.
12 changes: 10 additions & 2 deletions base/gmp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -707,8 +707,16 @@ end

factorial(x::BigInt) = isneg(x) ? BigInt(0) : MPZ.fac_ui(x)

binomial(n::BigInt, k::UInt) = MPZ.bin_ui(n, k)
binomial(n::BigInt, k::Integer) = k < 0 ? BigInt(0) : binomial(n, UInt(k))
function binomial(n::BigInt, k::Integer)
k < 0 && return BigInt(0)
k <= typemax(Culong) && return binomial(n, Culong(k))
n < 0 && return isodd(k) ? -binomial(k - n - 1, k) : binomial(k - n - 1, k)
κ = n - k
κ < 0 && return BigInt(0)
κ <= typemax(Culong) && return binomial(n, Culong(κ))
throw(OverflowError("Computation would exceed memory"))
end
binomial(n::BigInt, k::Culong) = MPZ.bin_ui(n, k)

==(x::BigInt, y::BigInt) = cmp(x,y) == 0
==(x::BigInt, i::Integer) = cmp(x,i) == 0
Expand Down
10 changes: 10 additions & 0 deletions test/combinatorics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ using Random: randcycle
@test binomial(Int64(67), Int64(29)) == binomial(BigInt(67), BigInt(29)) == 7886597962249166160
@test binomial(Int128(131), Int128(62)) == binomial(BigInt(131), BigInt(62)) == 157311720980559117816198361912717812000
@test_throws OverflowError binomial(Int64(67), Int64(30))

#Issue 48072
= parse(BigInt, "1" * "0"^13 * "666" * "0"^13 * "1")
@test binomial(∐, ∐ - 1) ==
@test binomial(∐, ∐ - 2) == 500000000000066600000000002218280000000000033300000000000000
@test binomial(∐, ∐ - 3) == binomial(∐, 3)
@test binomial(-big(2), ∐ - 3) == 1000000000000066599999999999999
@test_throws OverflowError binomial(big(2)^65, big(2)^64)
@test_throws OverflowError binomial(-big(2)^65, big(2)^64)
@test binomial(∐, 2 * ∐) == BigInt(0)
end

@testset "permutations" begin
Expand Down

0 comments on commit 832a67c

Please sign in to comment.