I was testing the basic version of the Fermat Factorization method, so I'm not using any improvement whatsoever. The code I wrote in Python works as fast as expected for those numbers obtained by relatively close primes.
import math
N = int(input("Insert a large number: "))
def fermat_factorization(N: int) -> list[int]:
if N % 2 == 0:
return [2, N // 2]
a = math.isqrt(N) + 1
b_square = a**2 - N
while not math.sqrt(b_square).is_integer():
a += 1
b_square = a**2 - N
b = math.isqrt(b_square)
return [a+b, a-b]
factors = fermat_factorization(N)
print(f"\nThe factor of {N} are {factors}")
However, upon checking for some large Mersenne primes (e.g. 2147483647), and playing with some more from here, the output missed the marked completely (2147483647 gets factorized into 268435456*8). Is there some error in the code or should I expect the algorithm to fail for large primes?
math.sqrtuses imprecise floating-point math; you should check ifmath.isqrt(b_square)**2 == b_square, for example. Not immediately sure if that’s the only issue, though.float.is_integer()is simply not as precise as you're hoping. Past a certain magnitude, all floats are detected as integers, simply because all of the significant digits that they're capable of representing are to the left of the decimal point.a = math.isqrt(N) + 1is not equivalent tomath.ceil(math.sqrt(N))which is what Fermat factorization needs to initializea. Usea = math.isqrt(N)thenif a**2 != N: a += 1. Perfect squares have a bug otherwise, e.g.25returns(25, 1)instead of(5, 5).