Skip to content

Commit f83d703

Browse files
authored
speed up factor for numbers with no large factors
1 parent ca0952b commit f83d703

File tree

1 file changed

+11
-9
lines changed

1 file changed

+11
-9
lines changed

src/Primes.jl

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -260,30 +260,28 @@ isprime(n::Int128) = n < 2 ? false :
260260
function factor!(n::T, h::AbstractDict{K,Int}) where {T<:Integer,K<:Integer}
261261
# check for special cases
262262
if n < 0
263-
h[-1] = 1
263+
h[-1] = 1 - h[-1]
264264
if isa(n, BitSigned) && n == typemin(T)
265-
h[2] = 8 * sizeof(T) - 1
265+
h[2] += 8 * sizeof(T) - 1
266266
return h
267267
else
268268
return factor!(checked_neg(n), h)
269269
end
270270
elseif n == 0
271-
h[n] = 1
271+
h[n] = 0
272272
return h
273273
elseif n <= length(MIN_FACTOR)
274274
while true
275275
n == 1 && return h
276276
if MIN_FACTOR[n]==1
277-
increment!(h, 1, n)
278-
return h
277+
return increment!(h, 1, n)
279278
else
280279
increment!(h, 1, MIN_FACTOR[n])
281280
n = div(n, MIN_FACTOR[n])
282281
end
283282
end
284283
elseif isprime(n)
285-
h[n] = 1
286-
return h
284+
return increment!(h, 1, n)
287285
end
288286
local p::T
289287
for p in 2:length(MIN_FACTOR)
@@ -296,11 +294,15 @@ function factor!(n::T, h::AbstractDict{K,Int}) where {T<:Integer,K<:Integer}
296294
n = q
297295
end
298296
# h[p] += num_p (about 2x faster, but the speed only matters for small numbers)
299-
num_p > 0 && increment!(h, num_p, p)
297+
if num_p > 0
298+
increment!(h, num_p, p)
299+
# if n is small, then recursing will hit the fast path.
300+
n < length(MIN_FACTOR) && return factor!(n, h)
301+
end
300302
p*p > n && break
301303
end
302304
n == 1 && return h
303-
isprime(n) && (h[n]=1; return h)
305+
isprime(n) && return increment!(h, 1, n)
304306
T <: BigInt || widemul(n - 1, n - 1) typemax(n) ? pollardfactors!(n, h) : pollardfactors!(widen(n), h)
305307
end
306308

0 commit comments

Comments
 (0)