Exemple #1
0
    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));
    }
Exemple #2
0
    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);
	}