Brute-force, single-threaded prime factorization

前端 未结 7 673
误落风尘
误落风尘 2020-12-07 22:08

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

7条回答
  •  -上瘾入骨i
    2020-12-07 22:47

    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);
    }
    

提交回复
热议问题