예제 #1
0
 void _Shift(Digits a, int n, Digits b)
 {
     if (a != b)
     {
         b._Set(a, _digitN);
     }
     Modular.ValidateData(a, _mod, _digitN);
     if (n < 0 && (_mod[0] & 1) == 0)
     {
         throw new ArgumentException();
     }
     while (n > 0)
     {
         int   shiftNow = n > Digit.BitN ? Digit.BitN : n;
         Digit carryOut = Digits.ShiftLost(b, shiftNow, b, _digitN)
         , qest         = _leftRecip
                          .EstQuotient(carryOut
                                       , b[_digitN - 1]
                                       , _digitN >= 2 ? b[_digitN - 2] : 0);
         carryOut -= Digits.Decumulate(_mod, qest, b, _digitN);
         if (carryOut != 0 || Digits.Compare(b, _mod, _digitN) >= 0)
         {
             carryOut -= Digits.Sub(b, _mod, b, _digitN);
         }
         Debug.Assert(carryOut == 0, "internal error");
         n -= shiftNow;
     }
     while (n < 0)
     {
         int   shiftNow = -n > Digit.BitN ? Digit.BitN : -n;
         Digit mul      = unchecked (0 - _rightRecip * b[0])
                          & Digit.MaxValue >> Digit.BitN - shiftNow
         , carry       = Digits.Accumulate(_mod, mul, b, _digitN)
         , lowBitNLost = Digits.ShiftLost(b, -shiftNow, b, _digitN);
         b[_digitN - 1] |= carry << Digit.BitN - shiftNow;
         Debug.Assert(lowBitNLost == 0, "internal error");
         n += shiftNow;
     }
 }
예제 #2
0
        internal static void Div(
            UInt64 num
            , Digit denom
            , Reciprocal recip
            , out Digit q
            , out Digit r
            )
        {
            Digit numHi = Hi(num)
            , numLo     = Lo(num)
            , qEst      = Digit.MaxValue - recip.EstQuotient(numHi, numLo, 0);
            UInt64 rEst = unchecked (
                ((UInt64)(numHi - denom) << Digit.BitN | numLo)
                + (UInt64)qEst * denom
                );

            q = unchecked ((Digit)(Hi(rEst) - qEst));
            r = unchecked (Lo(rEst) + (denom & Hi(rEst)));
            Digit qq, rr;

            Div(num, denom, out qq, out rr);
            Debug.Assert(qq == q && rr == r, "internal error");
        }