コード例 #1
0
ファイル: Rooter.cs プロジェクト: clewrus/AlgStruct
        internal RawNum Sqrt(RawNum left)
        {
            m_targetSquare    = left;
            m_targetSquareNum = m_targetSquare.OmgWrapper();

            m_rootAprox = OmgPool.GetRawZero();
            m_buffer    = OmgPool.GetRawZero();

            _FillInitialApproximation();

            while (!_AproxEqualToBuffer())
            {
                var aproxCopy = OmgPool.GetRawZero();
                aproxCopy.CopyFrom(m_rootAprox);

                var bufferCopy = OmgPool.GetRawZero();
                bufferCopy.CopyFrom(m_buffer);

                _MakeGeronIteration();

                if (OmgOp.Equal(aproxCopy.OmgWrapper(), m_buffer.OmgWrapper()) &&
                    OmgOp.Equal(bufferCopy.OmgWrapper(), m_rootAprox.OmgWrapper()) &&
                    OmgOp.Less(m_rootAprox.OmgWrapper(), m_buffer.OmgWrapper()))
                {
                    break;
                }

                OmgPool.ReleaseNumber(bufferCopy);
                OmgPool.ReleaseNumber(aproxCopy);
            }

            OmgPool.ReleaseNumber(m_buffer);
            return(m_rootAprox);
        }
コード例 #2
0
ファイル: Divider.cs プロジェクト: clewrus/AlgStruct
        public (OmgNum div, OmgNum mod) DivMod(OmgNum left, OmgNum right)
        {
            _InitializeDivModResult();

            if (OmgOp.Equal(right, s_two))
            {
                _DivModByTwo(left);
                return(m_divRes, m_modRes);
            }

            bool isNegative = left.IsNegative != right.IsNegative;

            m_divRes.IsNegative = isNegative;

            _FindDivModSolution(left.Raw, right.Raw);

            if (isNegative)
            {
                m_divRaw.Inc();
                _Subtract(right.Raw, m_modRaw);
            }

            _RemoveModLeadingZeros();
            return(m_divRes, m_modRes);
        }
コード例 #3
0
        private bool _MakeTest(OmgNum testBase)
        {
            OmgNum numDec         = (new OmgNum(m_tested)).Dec();
            OmgNum tested         = OmgOp.Pow(testBase, m_initialTested, m_tested);
            OmgNum iterationsLeft = new OmgNum(m_powerOfTwo);

            try {
                if (OmgOp.Equal(tested, OmgNum.GetConst(1)) || OmgOp.Equal(tested, numDec))
                {
                    return(true);
                }

                while (!iterationsLeft.IsZero())
                {
                    iterationsLeft.Dec();

                    var nwTested = OmgOp.Multiply(tested, tested, m_tested);
                    tested.Release();
                    tested = nwTested;

                    if (OmgOp.Equal(tested, numDec))
                    {
                        return(true);
                    }
                }

                return(false);
            }
            finally {
                numDec.Release();
                tested.Release();
                iterationsLeft.Release();
            }
        }
コード例 #4
0
        private OmgNum _FermaFactorization(Dictionary <OmgNum, OmgNum> result, OmgNum num)
        {
            OmgNum factor = null;

            if (OmgOp.DivMod(num, 2.ToOmgNum()).mod.IsZero())
            {
                factor = 2.ToOmgNum();
            }

            if (factor == null)
            {
                OmgNum a   = OmgOp.Sqrt(num);
                OmgNum aSq = OmgOp.Multiply(a, a);

                bool isSquare = OmgOp.Equal(num, aSq);
                if (isSquare)
                {
                    factor = a;
                }

                a.Inc();
                aSq = OmgOp.Multiply(a, a);
                var s = OmgOp.Subtract(aSq, num);

                while (factor == null)
                {
                    var testSqrt = OmgOp.Sqrt(s);
                    if (OmgOp.Equal(s, OmgOp.Multiply(testSqrt, testSqrt)))
                    {
                        factor = (OmgOp.Equal(testSqrt, a)) ? OmgOp.Add(a, a) : OmgOp.Subtract(a, testSqrt);
                        break;
                    }

                    a.Inc();
                    aSq = OmgOp.Multiply(a, a);
                    s   = OmgOp.Subtract(aSq, num);
                }
            }

            if (factor == null || factor.IsOne())
            {
                return(num);
            }

            OmgNum pow = _FindPow(ref num, factor);

            if (result.ContainsKey(factor))
            {
                result[factor] = OmgOp.Add(result[factor], pow);
            }
            else
            {
                result[factor] = pow;
            }

            return(num);
        }
コード例 #5
0
        private bool _IsSmallPrime(Dictionary <OmgNum, OmgNum> result, OmgNum num)
        {
            smallPrimesOmg ??= smallPrimes.Select(x => x.ToOmgNum()).ToArray();

            foreach (var prime in smallPrimesOmg)
            {
                if (OmgOp.Equal(prime, num))
                {
                    result[prime] = 1.ToOmgNum();
                    return(true);
                }
            }

            return(false);
        }
コード例 #6
0
        public OmgNum FindFactor(OmgNum n, int maxIterations = -1)
        {
            m_iterations = 0;

            m_current = n;

            OmgNum x = OmgOp.Random(1.ToOmgNum(), OmgOp.Subtract(n, 2.ToOmgNum()));
            OmgNum y = 1.ToOmgNum();

            OmgNum i     = 0.ToOmgNum();
            OmgNum stage = 2.ToOmgNum();

            OmgNum sub = OmgOp.Subtract(x, y).MakeAbs();
            OmgNum gcd = OmgOp.Gcd(n, sub);

            sub.Release();

            while (gcd.IsOne())
            {
                if (maxIterations >= 0 && m_iterations++ > maxIterations)
                {
                    return(null);
                }

                if (OmgOp.Equal(i, stage))
                {
                    y.Release();
                    y = new OmgNum(x);
                    stage.MultByTwo();
                }

                OmgNum xSquare = OmgOp.Multiply(x, x).Inc();
                x.Release();
                x = OmgOp.Mod(xSquare, n);
                xSquare.Release();

                i.Inc();

                sub = OmgOp.Subtract(x, y).MakeAbs();
                gcd.Release();
                gcd = OmgOp.Gcd(n, sub);
                sub.Release();
            }

            return(gcd);
        }
コード例 #7
0
        private OmgNum _FindFactorsWithPollard(Dictionary <OmgNum, OmgNum> result, OmgNum num)
        {
            num = num.Copy();

            while (!num.IsOne())
            {
                OmgNum factor = m_polard.FindFactor(num, maxIterations: 100000);
                if (factor == null || factor.IsOne() || OmgOp.Equal(factor, num))
                {
                    return(num);
                }

                OmgNum pow = _FindPow(ref num, factor);
                result[factor] = pow;
            }

            return(num);
        }
コード例 #8
0
        public bool IsPrime(OmgNum tested)
        {
            foreach (var prime in s_smallPrimes)
            {
                if (OmgOp.Less(tested, prime) || OmgOp.Equal(tested, prime))
                {
                    return(true);
                }

                var  mod         = OmgOp.Mod(tested, prime);
                bool isComposite = mod.IsZero();

                mod.Release();

                if (isComposite)
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #9
0
ファイル: Rooter.cs プロジェクト: clewrus/AlgStruct
 private bool _AproxEqualToBuffer()
 {
     return(OmgOp.Equal(m_rootAprox.OmgWrapper(), m_buffer.OmgWrapper()));
 }