public static BigInteger operator >>(BigInteger leftSide, int shiftCount) { if (leftSide == null) { throw new ArgumentNullException("leftSide"); } DigitsArray da = new DigitsArray(leftSide.m_digits); da.DataUsed = da.ShiftRight(shiftCount); if (leftSide.IsNegative) { for (int i = da.Count - 1; i >= da.DataUsed; i--) { da [i] = DigitsArray.AllBits; } DType mask = DigitsArray.HiBitSet; for (int i = 0; i < DigitsArray.DataSizeBits; i++) { if ((da [da.DataUsed - 1] & mask) == DigitsArray.HiBitSet) { break; } da [da.DataUsed - 1] |= mask; mask >>= 1; } da.DataUsed = da.Count; } return(new BigInteger(da)); }
private static void MultiDivide(BigInteger leftSide, BigInteger rightSide, out BigInteger quotient, out BigInteger remainder) { if (rightSide.IsZero) { throw new DivideByZeroException(); } DType val = rightSide.m_digits [rightSide.m_digits.DataUsed - 1]; int d = 0; for (uint mask = DigitsArray.HiBitSet; mask != 0 && (val & mask) == 0; mask >>= 1) { d++; } int remainderLen = leftSide.m_digits.DataUsed + 1; DType[] remainderDat = new DType[remainderLen]; leftSide.m_digits.CopyTo(remainderDat, 0, leftSide.m_digits.DataUsed); DigitsArray.ShiftLeft(remainderDat, d); rightSide = rightSide << d; ulong firstDivisor = rightSide.m_digits [rightSide.m_digits.DataUsed - 1]; ulong secondDivisor = (rightSide.m_digits.DataUsed < 2 ? (DType)0 : rightSide.m_digits [rightSide.m_digits.DataUsed - 2]); int divisorLen = rightSide.m_digits.DataUsed + 1; DigitsArray dividendPart = new DigitsArray(divisorLen, divisorLen); DType[] result = new DType[leftSide.m_digits.Count + 1]; int resultPos = 0; ulong carryBit = (ulong)0x1 << DigitsArray.DataSizeBits; // 0x100000000 for (int j = remainderLen - rightSide.m_digits.DataUsed, pos = remainderLen - 1; j > 0; j--, pos--) { ulong dividend = ((ulong)remainderDat [pos] << DigitsArray.DataSizeBits) + (ulong)remainderDat [pos - 1]; ulong qHat = (dividend / firstDivisor); ulong rHat = (dividend % firstDivisor); while (pos >= 2) { if (qHat == carryBit || (qHat * secondDivisor) > ((rHat << DigitsArray.DataSizeBits) + remainderDat [pos - 2])) { qHat--; rHat += firstDivisor; if (rHat < carryBit) { continue; } } break; } for (int h = 0; h < divisorLen; h++) { dividendPart [divisorLen - h - 1] = remainderDat [pos - h]; } BigInteger dTemp = new BigInteger(dividendPart); BigInteger rTemp = rightSide * (long)qHat; while (rTemp > dTemp) { qHat--; rTemp -= rightSide; } rTemp = dTemp - rTemp; for (int h = 0; h < divisorLen; h++) { remainderDat [pos - h] = rTemp.m_digits [rightSide.m_digits.DataUsed - h]; } result [resultPos++] = (DType)qHat; } Array.Reverse(result, 0, resultPos); quotient = new BigInteger(new DigitsArray(result)); int n = DigitsArray.ShiftRight(remainderDat, d); DigitsArray rDA = new DigitsArray(n, n); rDA.CopyFrom(remainderDat, 0, 0, rDA.DataUsed); remainder = new BigInteger(rDA); }
public static BigInteger operator >> (BigInteger leftSide, int shiftCount) { if (leftSide == null) { throw new ArgumentNullException("leftSide"); } DigitsArray da = new DigitsArray(leftSide.m_digits); da.DataUsed = da.ShiftRight(shiftCount); if (leftSide.IsNegative) { for (int i = da.Count - 1; i >= da.DataUsed; i--) { da[i] = DigitsArray.AllBits; } DType mask = DigitsArray.HiBitSet; for (int i = 0; i < DigitsArray.DataSizeBits; i++) { if ((da[da.DataUsed - 1] & mask) == DigitsArray.HiBitSet) { break; } da[da.DataUsed - 1] |= mask; mask >>= 1; } da.DataUsed = da.Count; } return new BigInteger(da); }