Skip to content

Commit f7b4ebe

Browse files
authored
fix issue #46665, prod(::Array{BigInt}) (#46667)
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.
1 parent 3793dac commit f7b4ebe

File tree

2 files changed

+7
-2
lines changed

2 files changed

+7
-2
lines changed

base/gmp.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -668,8 +668,12 @@ function prod(arr::AbstractArray{BigInt})
668668
# to account for the rounding to limbs in MPZ.mul!
669669
# (BITS_PER_LIMB-1 would typically be enough, to which we add
670670
# 1 for the initial multiplication by init=1 in foldl)
671-
nbits = GC.@preserve arr sum(arr; init=BITS_PER_LIMB) do x
672-
abs(x.size) * BITS_PER_LIMB - leading_zeros(unsafe_load(x.d))
671+
nbits = BITS_PER_LIMB
672+
for x in arr
673+
iszero(x) && return zero(BigInt)
674+
xsize = abs(x.size)
675+
lz = GC.@preserve x leading_zeros(unsafe_load(x.d, xsize))
676+
nbits += xsize * BITS_PER_LIMB - lz
673677
end
674678
init = BigInt(; nbits)
675679
MPZ.set_si!(init, 1)

test/gmp.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ let a, b
227227
@test 0 == sum(BigInt[]) isa BigInt
228228
@test prod(b) == foldl(*, b)
229229
@test 1 == prod(BigInt[]) isa BigInt
230+
@test prod(BigInt[0, 0, 0]) == 0 # issue #46665
230231
end
231232

232233
@testset "Iterated arithmetic" begin

0 commit comments

Comments
 (0)