Example #1
0
        static void Div(
            Digits numer
            , Digit den
            , Reciprocal recip
            , Digits q
            , int n
            , Digits r
            )
        {
            Digit carry = 0;
            int   nLeft = n;

            if (nLeft > 0 && numer[nLeft - 1] < den)
            {
                nLeft--;
                carry = numer[nLeft];
                if (q != null)
                {
                    q[nLeft] = 0;
                }
            }
            if (recip == null && nLeft < 2)
            {
                for (int i = nLeft; i-- != 0;)
                {
                    Digit qest = 0;
                    Digit2.Div((UInt64)carry << Digit.BitN | numer[i]
                               , den
                               , out qest
                               , out carry);
                    if (q != null)
                    {
                        q[i] = qest;
                    }
                }
            }
            else
            {
                if (recip == null)
                {
                    recip = new Reciprocal();
                    DivPrecondition(new Digits(new Digit[] { den }), 1, recip);
                }
                for (int i = nLeft; i-- != 0;)
                {
                    Digit qest = 0;
                    Digit2.Div((UInt64)carry << Digit.BitN | numer[i]
                               , den
                               , recip
                               , out qest
                               , out carry);
                    if (q != null)
                    {
                        q[i] = qest;
                    }
                }
            }
            r[0] = carry;
        }
Example #2
0
        DivPrecondition(Digits denom, int denomN, Reciprocal recip)
        {
            if (denom == null)
            {
                throw new ArgumentNullException();
            }
            if (denomN == 0 || denom[denomN - 1] == 0)
            {
                throw new ArgumentException();
            }
            int   recipBitShift = Digit.BitN - Digit.SigBitN(denom[denomN - 1]);
            Digit dlead2        = denom[denomN - 1]
            , dlead1            = denomN >= 2 ? denom[denomN - 2] : 0
            , dlead0            = denomN >= 3 ? denom[denomN - 3] : 0
            , dShiftHi          = dlead2 << recipBitShift
                         | dlead1 >> 1 >> Digit.BitN - 1 - recipBitShift
                , dShiftLo = dlead1 << recipBitShift
                         | dlead0 >> 1 >> Digit.BitN - 1 - recipBitShift;
            Digit recipMpy, r;

            Digit2.Div((UInt64)(Digit.MaxValue - dShiftHi) << Digit.BitN
                       | Digit.MaxValue - dShiftLo
                       , dShiftHi
                       , out recipMpy
                       , out r);
            if (Digit2.Hi((UInt64)recipMpy * dShiftLo) > r)
            {
                recipMpy -= 1;
            }
            r = (Digit.MaxValue >> recipBitShift) - denom[denomN - 1];
            for (int id = denomN; id-- != 0 && r < recipMpy;)
            {
                UInt64 test1 = (UInt64)r << Digit.BitN
                               | Digit.MaxValue - (id > 0 ? denom[id - 1] : 0)
                    , test2 = (UInt64)recipMpy * denom[id];
                if (test2 > test1)
                {
                    recipMpy -= 1; break;
                }
                test1 = test1 - test2;
                r     = Digit2.Lo(test1);
                if (Digit2.Hi(test1) != 0)
                {
                    break;
                }
            }
            recip._shiftBitN  = recipBitShift;
            recip._multiplier = recipMpy;
        }