Skip to content

Commit

Permalink
Hashing: Fix factor cancelation
Browse files Browse the repository at this point in the history
  • Loading branch information
barucden committed Nov 6, 2024
1 parent 4d37211 commit 86987ec
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 7 deletions.
14 changes: 8 additions & 6 deletions src/bigint.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,24 @@ function maxexp(n::Int)
end

"""
cancelfactor(x::BigInt, ::Val{N})
cancelfactor(x::BigInt, ::Val{N}, m::Integer)
Remove all occurrences of the factor `N` from `x`. The result is pair `(y, E)`
such that `x = y * N^E`.
Remove `m` occurrences of the factor `N` from `x`. The result is pair `(y, E)`
such that `x = y * N^E`. If `m` is not provided, all factors are removed.
"""
function cancelfactor(x::BigInt, ::Val{N}) where {N}
function cancelfactor(x::BigInt, ::Val{N}, m::Integer=typemax(Int)) where {N}
if iszero(x)
return x, 0
end

q = 0
while isdivisible(x, N)
while q < m && isdivisible(x, N)
d = N
q += 1
for e in 2:maxexp(N)
isdivisible(x, d * N) || break
if (q == m) || !isdivisible(x, d * N)
break
end
d *= N
q += 1
end
Expand Down
2 changes: 1 addition & 1 deletion src/hash.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ function Base.decompose(x::Decimal)
if x.q 0
return (coef * big(5)^x.q, x.q, BigOne)
else
coef, exp = cancelfactor(coef, Val(5))
coef, exp = cancelfactor(coef, Val(5), -x.q)
q = -x.q - exp
return (coef, x.q, big(5) ^ q)
end
Expand Down
1 change: 1 addition & 0 deletions test/test_hash.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ using Test
@test hash(Decimal(-3)) == hash(-3)
@test hash(Decimal(-0.09375)) == hash(-0.09375)
@test hash(Decimal(1.1)) == hash(1.1)
@test hash(Decimal(0.3)) == hash(0.3)

# Equality implies same hash
@test hash(Decimal(0, 100, 0)) == hash(Decimal(0, 10, 1))
Expand Down

0 comments on commit 86987ec

Please sign in to comment.