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