1:  // Author & Copyright : Peter Luschny
   2:  // Created: 2010-01-15
   3:  // License: LGPL version 2.1 or (at your option)
   4:  // Creative Commons Attribution-ShareAlike 3.0
   5:   
   6:  #ifndef PRIMESWING_H_
   7:  #define PRIMESWING_H_
   8:   
   9:  #include "lmp.h"
  10:   
  11:  static const ulong smallOddSwing[] =  {
  12:      1, 1, 1, 3, 3, 15, 5, 35, 35, 315, 63, 693, 231, 3003, 429,
  13:      6435, 6435, 109395, 12155, 230945, 46189, 969969, 88179,
  14:      2028117, 676039, 16900975, 1300075, 35102025, 5014575,
  15:      145422675, 9694845, 300540195, 300540195 };
  16:   
  17:  class PrimeSwing {
  18:  public:
  19:   
  20:      // Computes the factorial of an integer.
  21:      static void Factorial(Xint fact, ulong n);
  22:   
  23:      // Computes the factorial of an integer using threads.
  24:      static void ParallelFactorial(Xint fact, ulong n);
  25:   
  26:      // Computes the double factorial (Swing algo).
  27:      static void DoubleFactorial(Xint fact, ulong n);
  28:   
  29:      // Computes the double factorial (Swing algo).
  30:      static void ParallelDoubleFactorial(Xint fact, ulong n);
  31:   
  32:  private:
  33:   
  34:      static const unsigned int THRESHOLD = 20;
  35:      static const ulong SOSLEN = 33;
  36:   
  37:      static long GetIndexOf(ulong* p, ulong val, slong low, slong high)
  38:      {
  39:          slong lim = high;
  40:          while (low < high)
  41:          {
  42:              slong mid = low + (high - low) / 2;
  43:              if (p[mid] < val) { low = mid + 1; }
  44:              else { high = mid; }
  45:          }
  46:          if (low >= lim) { return low; }
  47:          if (p[low] == val) { low++; }
  48:   
  49:          return low;
  50:      }
  51:  };
  52:   
  53:  #endif // PRIMESWING_H_