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; } }
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"); }