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

            var sieve = new PrimeSieve(n);

            var task2 = Task.Factory.StartNew <XInt>(() =>
            {
                this.results2       = new IAsyncResult[XMath.FloorLog2(n)];
                this.swingDelegate2 = Swing2;
                this.taskCounter2   = 0;

                var N = n;

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

            this.results3       = new IAsyncResult[XMath.FloorLog2(n)];
            this.swingDelegate3 = Swing3;
            this.taskCounter3   = 0;

            var m = n;

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

            var task3Result = this.RecFactorial3(n);

            return((task2.Result * task3Result) << (n - XMath.BitCount(n)));
        }
        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 < 20) { return XMath.Factorial(n); }

            var sieve = new PrimeSieve(n);

            var task2 = Task.Factory.StartNew<XInt>(() =>
            {
                this.results2 = new IAsyncResult[XMath.FloorLog2(n)];
                this.swingDelegate2 = Swing2;
                this.taskCounter2 = 0;

                var N = n;

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

            this.results3 = new IAsyncResult[XMath.FloorLog2(n)];
            this.swingDelegate3 = Swing3;
            this.taskCounter3 = 0;

            var m = n;

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

            var task3Result = this.RecFactorial3(n);

            return (task2.Result * task3Result) << (n - XMath.BitCount(n));
        }
Example #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)));
        }