Skip to content

Commit

Permalink
fix issue #46665, prod(::Array{BigInt})
Browse files Browse the repository at this point in the history
The way we were counting the number of bits was assigning a negative number
to `0`, which could lead to a negative total number of bits. Better to just
exit early in this case.
Also, the estimate was slightly off because we were counting the number of leading
zeros in the least significant limb, instead of the most significant.
  • Loading branch information
rfourquet committed Sep 7, 2022
1 parent 83658d2 commit a8911ff
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 2 deletions.
8 changes: 6 additions & 2 deletions base/gmp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -668,8 +668,12 @@ function prod(arr::AbstractArray{BigInt})
# to account for the rounding to limbs in MPZ.mul!
# (BITS_PER_LIMB-1 would typically be enough, to which we add
# 1 for the initial multiplication by init=1 in foldl)
nbits = GC.@preserve arr sum(arr; init=BITS_PER_LIMB) do x
abs(x.size) * BITS_PER_LIMB - leading_zeros(unsafe_load(x.d))
nbits = BITS_PER_LIMB
xsize = abs(x.size)
for x in arr
iszero(x) && return zero(BigInt)
lz = GC.@preserve arr leading_zeros(unsafe_load(x.d, xsize))
nbits += xsize * BITS_PER_LIMB - lz
end
init = BigInt(; nbits)
MPZ.set_si!(init, 1)
Expand Down
1 change: 1 addition & 0 deletions test/gmp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ let a, b
@test 0 == sum(BigInt[]) isa BigInt
@test prod(b) == foldl(*, b)
@test 1 == prod(BigInt[]) isa BigInt
@test prod(BigInt[0, 0, 0]) == 0 # issue #46665
end

@testset "Iterated arithmetic" begin
Expand Down

0 comments on commit a8911ff

Please sign in to comment.