public XInt Factorial(int n)
        {
            if (n < 20)
            {
                return(XMath.Factorial(n));
            }

            this.sieve = new PrimeSieve(n);

            return(this.RecFactorial(n));
        }
        public XInt Factorial(int n)
        {
            if (n < 20)
            {
                return(XMath.Factorial(n));
            }

            var log2N = XMath.FloorLog2(n);
            var j     = log2N;
            var hN    = n;

            this.primeList  = new int[log2N][];
            this.listLength = new int[log2N];
            this.bound      = new int[log2N];
            this.tower      = new int[log2N + 1];

            while (true)
            {
                this.tower[j] = hN;
                if (hN == 1)
                {
                    break;
                }
                this.bound[--j] = hN / 3;
                var pLen = hN < 4 ? 6 : (int)(2.0 * (XMath.FloorSqrt(hN)
                                                     + (double)hN / (XMath.Log2(hN) - 1)));
                this.primeList[j] = new int[pLen];
                hN >>= 1;
            }

            this.tower[0] = 2;
            this.PrimeFactors(n);

            var init         = this.listLength[0] == 0 ? 1 : 3;
            var oddFactorial = new XInt(init);

            var results = new XInt[log2N];

            Parallel.For(1, log2N, i =>
                         results[i] = XMath.Product(this.primeList[i], 0, this.listLength[i])
                         );

            for (var i = 1; i < log2N; i++)
            {
                oddFactorial = XInt.Pow(oddFactorial, 2);
                oddFactorial = oddFactorial * results[i];
            }

            return(oddFactorial << (n - XMath.BitCount(n)));
        }
예제 #3
0
        public XInt Factorial(int n)
        {
            if (n < 20)
            {
                return(XMath.Factorial(n));
            }

            this.cache = new Dictionary <int, CachedPrimorial>();
            this.sieve = new PrimeSieve(n);

            var pLen = (int)(2.0 * (XMath.FloorSqrt(n)
                                    + (double)n / (XMath.Log2(n) - 1)));

            this.primeList = new int[pLen];

            var exp2 = n - XMath.BitCount(n);

            return(this.RecFactorial(n) << exp2);
        }
예제 #4
0
        public XInt Factorial(int n)
        {
            if (n < 20)
            {
                return(XMath.Factorial(n));
            }

            this.sieve = new PrimeSieve(n);
            var log2N = XMath.FloorLog2(n);

            SwingDelegate swingDelegate = this.Swing;
            var           results       = new IAsyncResult[log2N];

            int h = 0, shift = 0, taskCounter = 0;

            // -- It is more efficient to add the big intervals
            // -- first and the small ones later!
            while (h != n)
            {
                shift += h;
                h      = n >> log2N--;
                if (h > 2)
                {
                    results[taskCounter++] = swingDelegate.BeginInvoke(h, null, null);
                }
            }

            XInt p = XInt.One, r = XInt.One, rl = XInt.One;

            for (var i = 0; i < taskCounter; i++)
            {
                var t = rl * swingDelegate.EndInvoke(results[i]);
                p  = p * t;
                rl = r;
                r  = r * p;
            }

            return(r << shift);
        }
        public XInt Factorial(int n)
        {
            if (n < 20)
            {
                return(XMath.Factorial(n));
            }

            var sieve = new PrimeSieve(n);

            this.results       = new IAsyncResult[XMath.FloorLog2(n)];
            this.swingDelegate = Swing; this.taskCounter = 0;
            var N = n;

            // -- It is more efficient to add the big swings
            // -- first and the small ones later!
            while (N >= Smallswing)
            {
                this.results[this.taskCounter++] = this.swingDelegate.BeginInvoke(sieve, N, null, null);
                N >>= 1;
            }

            return(this.RecFactorial(n) << (n - XMath.BitCount(n)));
        }
        public XInt Factorial(int n)
        {
            if (n < 0)
            {
                throw new System.ArgumentOutOfRangeException(
                          this.Name + ": " + nameof(n) + " >= 0 required, but was " + n);
            }

            if (n < 20)
            {
                return(XMath.Factorial(n));
            }

            var lgN = XMath.FloorLog2(n);
            var piN = 2 + (15 * n) / (8 * (lgN - 1));

            this.primeList = new int[piN];
            this.multiList = new int[piN];

            var len  = this.PrimeFactors(n);
            var exp2 = n - XMath.BitCount(n);

            return(this.RepeatedSquare(len, 1) << exp2);
        }