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