Up for consideration is the following function which can be used to (relatively quickly) factor a 64-bit unsigned integer into its prime factors. Note that the factoring is
Incorporating some ideas from Omnifarious, plus other improvements:
// system specific typedef for ulong should go here (or use boost::uint64_t)
typedef unsigned __int64 ulong;
typedef std::vector ULongVector;
// Caller needs to pass in an empty factors vector
void GetFactors(ULongVector &factors, ulong num)
{
if (num<2)
return;
ulong workingNum=num;
// Factor out factors of 2
while (workingNum%2==0)
{
factors.push_back(2);
workingNum/=2;
}
// Factor out factors of 3
while (workingNum%3==0)
{
factors.push_back(3);
workingNum/=3;
}
if (workingNum==1)
return;
// Factor out factors >=5
ulong nextOffset=2;
char nextShift = 1;
ulong n = 5;
ulong nn = 25;
do {
// Is workingNum divisible by n?
if (workingNum%n==0)
{
// n is a factor!
// so is the number multiplied by n to get workingNum
// Insert n into the list of factors
factors.push_back(n);
// Divide working number by n
workingNum/=n;
// Test for done...
if (workingNum==1)
return;
// Try n again
}
else {
nn += (n << (nextShift+1)) + (1<<(nextShift*2)); // (n+b)^2 = n^2 + 2*n*b + b*2
n += nextOffset;
nextOffset ^= 6;
nextShift ^= 3;
// invariant: nn == n*n
if (n & 0x100000000LL) break; // careful of integer wraparound in n^2
}
} while (nn <= workingNum);
// workingNum is prime, add it to the list of factors
factors.push_back(workingNum);
}