Beispiel #1
0
        public XInt Factorial(int n)
        {
            if (n < 0)
            {
                throw new System.ArgumentOutOfRangeException(
                          this.Name + ": " + nameof(n) + " >= 0 required, but was " + n);
            }

            if (n < 2)
            {
                return(XInt.One);
            }

            var p = XInt.One;
            var r = XInt.One;

            int h = 0, shift = 0, k = 1;
            var log2N = XMath.FloorLog2(n);

            while (h != n)
            {
                shift += h;
                h      = n >> log2N--;
                var high = (h & 1) == 1 ? h : h - 1;

                while (k != high)
                {
                    k += 2;
                    p *= k;
                }
                r *= p;
            }

            return(r << shift);
        }
        public int Factor(int n)
        {
            this.n = n;

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

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

            return(this.card = this.PrimeFactors(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)));
        }
        XInt IFactorialFunction.Factorial(int n)
        {
            if (n < 0)
            {
                throw new System.ArgumentOutOfRangeException(
                          this.Name + ": " + nameof(n) + " >= 0 required, but was " + n);
            }

            if (n < 2)
            {
                return(XInt.One);
            }

            var             log2N        = XMath.FloorLog2(n);
            ProductDelegate prodDelegate = Product;
            var             results      = new IAsyncResult[log2N];

            int high = n, low = n >> 1, shift = low, taskCounter = 0;

            // -- It is more efficient to add the big intervals
            // -- first and the small ones later!
            while ((low + 1) < high)
            {
                results[taskCounter++] = prodDelegate.BeginInvoke(low + 1, high, null, null);
                high   = low;
                low  >>= 1;
                shift += low;
            }

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

            while (--taskCounter >= 0)
            {
                var I = Task.Factory.StartNew(() => r * p);
                var t = p * prodDelegate.EndInvoke(results[taskCounter]);
                r = I.Result;
                p = t;
            }

            return((r * p) << shift);
        }
Beispiel #5
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);
        }
Beispiel #6
0
        public XInt Factorial(int n)
        {
            if (n < 0)
            {
                throw new System.ArgumentOutOfRangeException(
                          this.Name + ": " + nameof(n) + " >= 0 required, but was " + n);
            }

            if (n < 2)
            {
                return(XInt.One);
            }

            var p = XInt.One;
            var r = XInt.One;

            this.currentN = XInt.One;

            int h = 0, shift = 0, high = 1;
            var log2N = XMath.FloorLog2(n);

            while (h != n)
            {
                shift += h;
                h      = n >> log2N--;
                var len = high;
                high = (h - 1) | 1;
                len  = (high - len) / 2;

                if (len > 0)
                {
                    p *= this.Product(len);
                    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);
        }