Ejemplo n.º 1
0
        private void _FindDivModSolution(RawNum left, RawNum right)
        {
            if (_IsTrivial(left, right))
            {
                m_modRaw.CopyFrom(left);
                return;
            }

            m_buffer = OmgPool.GetRawZero();
            _CalcDivMod(left, right);
            OmgPool.ReleaseNumber(m_buffer);

            m_divRaw.Digits.Reverse();
            m_modRaw.Digits.Reverse();
        }
Ejemplo n.º 2
0
        internal RawNum ExtendedGcd(RawNum left, RawNum right, out OmgNum x, out OmgNum y)
        {
            if (left.IsZero())
            {
                x = 0.ToOmgNum();
                y = 1.ToOmgNum();

                RawNum gcd = OmgPool.GetRawZero();
                gcd.CopyFrom(right);
                return(gcd);
            }

            var divModRes = OmgOp.DivMod(right.OmgWrapper(), left.OmgWrapper());

            RawNum gcdRes = ExtendedGcd(divModRes.mod.Raw, left, out OmgNum x2, out OmgNum y2);

            divModRes.mod.Release();

            OmgNum multRes = OmgOp.Multiply(divModRes.div, x2);

            divModRes.div.Release();

            x = OmgOp.Subtract(y2, multRes);
            y2.Release();
            multRes.Release();

            y = x2;
            return(gcdRes);
        }
Ejemplo n.º 3
0
        private void _DivModByTwo(OmgNum num)
        {
            var rawNum = num.Raw;

            if (!rawNum.IsZero() && ((rawNum.Digits[0] & 1) == 1))
            {
                m_modRaw.Digits.Add(1);
            }

            m_divRaw.CopyFrom(rawNum);
            m_divRaw.DivByTwo();
        }
Ejemplo n.º 4
0
        internal RawNum FindGcd(RawNum left, RawNum right)
        {
            if (left.IsZero())
            {
                RawNum gcd = OmgPool.GetRawZero();
                gcd.CopyFrom(right);
                return(gcd);
            }

            var divModRes = OmgOp.DivMod(right.OmgWrapper(), left.OmgWrapper());

            divModRes.div.Release();

            RawNum gcdRes = FindGcd(divModRes.mod.Raw, left);

            divModRes.mod.Release();

            return(gcdRes);
        }
Ejemplo n.º 5
0
        internal RawNum MultiplyKaratsuba(RawNum left, RawNum right)
        {
            if (left.IsZero() || right.IsZero())
            {
                return(OmgPool.GetRawZero());
            }

            int n = Math.Min(left.Size, right.Size);

            (RawNum head, RawNum tail)leftSep  = _SeparateHead(left, n);
            (RawNum head, RawNum tail)rightSep = _SeparateHead(right, n);

            RawNum headsProd = Multiply(leftSep.head, rightSep.head);
            RawNum tailsProd = Multiply(leftSep.tail, rightSep.tail);

            RawNum headTail = Multiply(leftSep.head, rightSep.tail);
            RawNum tailHead = Multiply(leftSep.tail, rightSep.head);

            OmgNum midSum = OmgOp.Add(new OmgNum(headTail), new OmgNum(tailHead));

            m_multRaw = OmgPool.GetRawZero();

            m_multRaw.CopyFrom(tailsProd);
            midSum.Raw.Digits.InsertRange(0, Enumerable.Repeat <uint>(0, n));
            headsProd.Digits.InsertRange(0, Enumerable.Repeat <uint>(0, 2 * n));

            OmgNum res      = OmgOp.Add(new OmgNum(tailsProd), midSum);
            OmgNum finalRes = OmgOp.Add(new OmgNum(headsProd), res);

            midSum.Release();
            res.Release();
            OmgPool.ReleaseNumber(headTail);
            OmgPool.ReleaseNumber(tailHead);

            return(finalRes.Raw);
        }