Ejemplo n.º 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));
    }
Ejemplo n.º 2
0
    /// <summary>
    /// Negates the BigInteger, that is, if the BigInteger is negative return a positive BigInteger, and if the
    /// BigInteger is negative return the postive.
    /// </summary>
    /// <param name="leftSide">A BigInteger operand.</param>
    /// <returns>The value of the <paramref name="this" /> negated.</returns>
    public static BigInteger operator -(BigInteger leftSide)
    {
        if (object.ReferenceEquals(leftSide, null))
        {
            throw new ArgumentNullException("leftSide");
        }

        if (leftSide.IsZero)
        {
            return(new BigInteger(0));
        }

        DigitsArray da = new DigitsArray(leftSide.m_digits.DataUsed + 1, leftSide.m_digits.DataUsed + 1);

        for (int i = 0; i < da.Count; i++)
        {
            da [i] = (DType)(~(leftSide.m_digits [i]));
        }

        // add one to result (1's complement + 1)
        bool carry = true;
        int  index = 0;

        while (carry && index < da.Count)
        {
            long val = (long)da [index] + 1;
            da [index] = (DType)(val & DigitsArray.AllBits);
            carry      = ((val >> DigitsArray.DataSizeBits) > 0);
            index++;
        }

        return(new BigInteger(da));
    }
Ejemplo n.º 3
0
 /// <summary>
 /// Creates a BigInteger with the value of the operand. Can never be negative.
 /// </summary>
 /// <param name="number">A unsigned long.</param>
 public BigInteger(ulong number)
 {
     m_digits = new DigitsArray((8 / DigitsArray.DataSizeOf) + 1, 0);
     while (number != 0 && m_digits.DataUsed < m_digits.Count)
     {
         m_digits [m_digits.DataUsed] = (DType)(number & DigitsArray.AllBits);
         number >>= DigitsArray.DataSizeBits;
         m_digits.DataUsed++;
     }
     m_digits.ResetDataUsed();
 }
Ejemplo n.º 4
0
    public static BigInteger operator ~(BigInteger leftSide)
    {
        DigitsArray da = new DigitsArray(leftSide.m_digits.Count);

        for (int idx = 0; idx < da.Count; idx++)
        {
            da [idx] = (DType)(~(leftSide.m_digits [idx]));
        }

        return(new BigInteger(da));
    }
Ejemplo n.º 5
0
    public static BigInteger operator ^(BigInteger leftSide, BigInteger rightSide)
    {
        int         len = System.Math.Max(leftSide.m_digits.DataUsed, rightSide.m_digits.DataUsed);
        DigitsArray da  = new DigitsArray(len, len);

        for (int idx = 0; idx < len; idx++)
        {
            da [idx] = (DType)(leftSide.m_digits [idx] ^ rightSide.m_digits [idx]);
        }
        return(new BigInteger(da));
    }
Ejemplo n.º 6
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.ShiftLeftWithoutOverflow(shiftCount);

        return(new BigInteger(da));
    }
Ejemplo n.º 7
0
    /// <summary>
    /// Adds two BigIntegers and returns a new BigInteger that represents the sum.
    /// </summary>
    /// <param name="leftSide">A BigInteger</param>
    /// <param name="rightSide">A BigInteger</param>
    /// <returns>The BigInteger result of adding <paramref name="leftSide" /> and <paramref name="rightSide" />.</returns>
    public static BigInteger operator +(BigInteger leftSide, BigInteger rightSide)
    {
        int         size = System.Math.Max(leftSide.m_digits.DataUsed, rightSide.m_digits.DataUsed);
        DigitsArray da   = new DigitsArray(size + 1);

        long carry = 0;

        for (int i = 0; i < da.Count; i++)
        {
            long sum = (long)leftSide.m_digits [i] + (long)rightSide.m_digits [i] + carry;
            carry  = (long)(sum >> DigitsArray.DataSizeBits);
            da [i] = (DType)(sum & DigitsArray.AllBits);
        }

        return(new BigInteger(da));
    }
Ejemplo n.º 8
0
    /// <summary>
    /// Substracts two BigIntegers and returns a new BigInteger that represents the sum.
    /// </summary>
    /// <param name="leftSide">A BigInteger</param>
    /// <param name="rightSide">A BigInteger</param>
    /// <returns>The BigInteger result of substracting <paramref name="leftSide" /> and <paramref name="rightSide" />.</returns>
    public static BigInteger operator -(BigInteger leftSide, BigInteger rightSide)
    {
        int         size = System.Math.Max(leftSide.m_digits.DataUsed, rightSide.m_digits.DataUsed) + 1;
        DigitsArray da   = new DigitsArray(size);

        long carry = 0;

        for (int i = 0; i < da.Count; i++)
        {
            long diff = (long)leftSide.m_digits [i] - (long)rightSide.m_digits [i] - carry;
            da [i] = (DType)(diff & DigitsArray.AllBits);
            da.DataUsed++;
            carry = ((diff < 0) ? 1 : 0);
        }
        return(new BigInteger(da));
    }
Ejemplo n.º 9
0
    private void Construct(string digits, int radix)
    {
        if (digits == null)
        {
            throw new ArgumentNullException("digits");
        }

        BigInteger multiplier = new BigInteger(1);
        BigInteger result     = new BigInteger();

        digits = digits.ToUpper(System.Globalization.CultureInfo.CurrentCulture).Trim();

        int nDigits = (digits [0] == '-' ? 1 : 0);

        for (int idx = digits.Length - 1; idx >= nDigits; idx--)
        {
            int d = (int)digits [idx];
            if (d >= '0' && d <= '9')
            {
                d -= '0';
            }
            else if (d >= 'A' && d <= 'Z')
            {
                d = (d - 'A') + 10;
            }
            else
            {
                throw new ArgumentOutOfRangeException("digits");
            }

            if (d >= radix)
            {
                throw new ArgumentOutOfRangeException("digits");
            }
            result     += (multiplier * d);
            multiplier *= radix;
        }

        if (digits [0] == '-')
        {
            result = -result;
        }

        this.m_digits = result.m_digits;
    }
Ejemplo n.º 10
0
    private static void SingleDivide(BigInteger leftSide, BigInteger rightSide, out BigInteger quotient, out BigInteger remainder)
    {
        if (rightSide.IsZero)
        {
            throw new DivideByZeroException();
        }

        DigitsArray remainderDigits = new DigitsArray(leftSide.m_digits);

        remainderDigits.ResetDataUsed();

        int   pos      = remainderDigits.DataUsed - 1;
        ulong divisor  = (ulong)rightSide.m_digits [0];
        ulong dividend = (ulong)remainderDigits [pos];

        DType[] result = new DType[leftSide.m_digits.Count];
        leftSide.m_digits.CopyTo(result, 0, result.Length);
        int resultPos = 0;

        if (dividend >= divisor)
        {
            result [resultPos++]  = (DType)(dividend / divisor);
            remainderDigits [pos] = (DType)(dividend % divisor);
        }
        pos--;

        while (pos >= 0)
        {
            dividend                  = ((ulong)(remainderDigits [pos + 1]) << DigitsArray.DataSizeBits) + (ulong)remainderDigits [pos];
            result [resultPos++]      = (DType)(dividend / divisor);
            remainderDigits [pos + 1] = 0;
            remainderDigits [pos--]   = (DType)(dividend % divisor);
        }
        remainder = new BigInteger(remainderDigits);

        DigitsArray quotientDigits = new DigitsArray(resultPos + 1, resultPos);
        int         j = 0;

        for (int i = quotientDigits.DataUsed - 1; i >= 0; i--, j++)
        {
            quotientDigits [j] = result [i];
        }
        quotient = new BigInteger(quotientDigits);
    }
Ejemplo n.º 11
0
    private void ConstructFrom(byte[] array, int offset, int length)
    {
        if (array == null)
        {
            throw new ArgumentNullException("array");
        }
        if (offset > array.Length || length > array.Length)
        {
            throw new ArgumentOutOfRangeException("offset");
        }
        if (length > array.Length || (offset + length) > array.Length)
        {
            throw new ArgumentOutOfRangeException("length");
        }

        int estSize  = length / 4;
        int leftOver = length & 3;

        if (leftOver != 0)
        {
            ++estSize;
        }

        m_digits = new DigitsArray(estSize + 1, 0);                          // alloc one extra since we can't init -'s from here.

        for (int i = offset + length - 1, j = 0; (i - offset) >= 3; i -= 4, j++)
        {
            m_digits [j] = (DType)((array [i - 3] << 24) + (array [i - 2] << 16) + (array [i - 1] << 8) + array [i]);
            m_digits.DataUsed++;
        }

        DType accumulator = 0;

        for (int i = leftOver; i > 0; i--)
        {
            DType digit = array [offset + leftOver - i];
            digit        = (digit << ((i - 1) * 8));
            accumulator |= digit;
        }
        m_digits [m_digits.DataUsed] = accumulator;

        m_digits.ResetDataUsed();
    }
Ejemplo n.º 12
0
    /// <summary>
    /// Multiply two BigIntegers returning the result.
    /// </summary>
    /// <remarks>
    /// See Knuth.
    /// </remarks>
    /// <param name="leftSide">A BigInteger.</param>
    /// <param name="rightSide">A BigInteger</param>
    /// <returns></returns>
    public static BigInteger operator *(BigInteger leftSide, BigInteger rightSide)
    {
        if (object.ReferenceEquals(leftSide, null))
        {
            throw new ArgumentNullException("leftSide");
        }
        if (object.ReferenceEquals(rightSide, null))
        {
            throw new ArgumentNullException("rightSide");
        }

        bool leftSideNeg  = leftSide.IsNegative;
        bool rightSideNeg = rightSide.IsNegative;

        leftSide  = Abs(leftSide);
        rightSide = Abs(rightSide);

        DigitsArray da = new DigitsArray(leftSide.m_digits.DataUsed + rightSide.m_digits.DataUsed);

        da.DataUsed = da.Count;

        for (int i = 0; i < leftSide.m_digits.DataUsed; i++)
        {
            ulong carry = 0;
            for (int j = 0, k = i; j < rightSide.m_digits.DataUsed; j++, k++)
            {
                ulong val = ((ulong)leftSide.m_digits [i] * (ulong)rightSide.m_digits [j]) + (ulong)da [k] + carry;

                da [k] = (DType)(val & DigitsArray.AllBits);
                carry  = (val >> DigitsArray.DataSizeBits);
            }

            if (carry != 0)
            {
                da [i + rightSide.m_digits.DataUsed] = (DType)carry;
            }
        }

        //da.ResetDataUsed();
        BigInteger result = new BigInteger(da);

        return(leftSideNeg != rightSideNeg ? -result : result);
    }
Ejemplo n.º 13
0
 /// <summary>
 /// Copy constructor, doesn't copy the digits parameter, assumes <code>this</code> owns the DigitsArray.
 /// </summary>
 /// <remarks>The <paramef name="digits" /> parameter is saved and reset.</remarks>
 /// <param name="digits"></param>
 private BigInteger(DigitsArray digits)
 {
     digits.ResetDataUsed();
     this.m_digits = digits;
 }
Ejemplo n.º 14
0
	/// <summary>
	/// Create a BigInteger with an integer value of 0.
	/// </summary>
	public BigInteger()
	{
		m_digits = new DigitsArray(1, 1);
	}
Ejemplo n.º 15
0
	/// <summary>
	/// Creates a BigInteger with the value of the operand. Can never be negative.
	/// </summary>
	/// <param name="number">A unsigned long.</param>
	public BigInteger(ulong number)
	{
		m_digits = new DigitsArray((8 / DigitsArray.DataSizeOf) + 1, 0);
		while (number != 0 && m_digits.DataUsed < m_digits.Count)
		{
			m_digits[m_digits.DataUsed] = (DType)(number & DigitsArray.AllBits);
			number >>= DigitsArray.DataSizeBits;
			m_digits.DataUsed++;
		}
		m_digits.ResetDataUsed();
	}
Ejemplo n.º 16
0
	/// <summary>
	/// Substracts two BigIntegers and returns a new BigInteger that represents the sum.
	/// </summary>
	/// <param name="leftSide">A BigInteger</param>
	/// <param name="rightSide">A BigInteger</param>
	/// <returns>The BigInteger result of substracting <paramref name="leftSide" /> and <paramref name="rightSide" />.</returns>
	public static BigInteger operator - (BigInteger leftSide, BigInteger rightSide)
	{
		int size = System.Math.Max(leftSide.m_digits.DataUsed, rightSide.m_digits.DataUsed) + 1;
		DigitsArray da = new DigitsArray(size);
		
		long carry = 0;
		for (int i = 0; i < da.Count; i++)
		{
			long diff = (long)leftSide.m_digits[i] - (long)rightSide.m_digits[i] - carry;
			da[i] = (DType)(diff & DigitsArray.AllBits);
			da.DataUsed++;
			carry = ((diff < 0) ? 1 : 0);
		}
		return new BigInteger(da);
	}
Ejemplo n.º 17
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);
    }
Ejemplo n.º 18
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.ShiftLeftWithoutOverflow(shiftCount);
		
		return new BigInteger(da);
	}
Ejemplo n.º 19
0
	private void Construct(string digits, int radix)
	{
		if (digits == null)
		{
			throw new ArgumentNullException("digits");
		}
		
		BigInteger multiplier = new BigInteger(1);
		BigInteger result = new BigInteger();
		digits = digits.ToUpper(System.Globalization.CultureInfo.CurrentCulture).Trim();
		
		int nDigits = (digits[0] == '-' ? 1 : 0);
		
		for (int idx = digits.Length - 1; idx >= nDigits ; idx--)
		{
			int d = (int)digits[idx];
			if (d >= '0' && d <= '9')
			{
				d -= '0';
			}
			else if (d >= 'A' && d <= 'Z')
			{
				d = (d - 'A') + 10;
			}
			else
			{
				throw new ArgumentOutOfRangeException("digits");
			}
			
			if (d >= radix)
			{
				throw new ArgumentOutOfRangeException("digits");
			}
			result += (multiplier * d);
			multiplier *= radix;
		}
		
		if (digits[0] == '-')
		{
			result = -result;
		}
		
		this.m_digits = result.m_digits;
	}
Ejemplo n.º 20
0
	/// <summary>
	/// Copy constructor, doesn't copy the digits parameter, assumes <code>this</code> owns the DigitsArray.
	/// </summary>
	/// <remarks>The <paramef name="digits" /> parameter is saved and reset.</remarks>
	/// <param name="digits"></param>
	private BigInteger(DigitsArray digits)
	{
		digits.ResetDataUsed();
		this.m_digits = digits;
	}
Ejemplo n.º 21
0
	public static BigInteger operator ~ (BigInteger leftSide)
	{
		DigitsArray da = new DigitsArray(leftSide.m_digits.Count);
		for(int idx = 0; idx < da.Count; idx++)
		{
			da[idx] = (DType)(~(leftSide.m_digits[idx]));
		}
		
		return new BigInteger(da);
	}
Ejemplo n.º 22
0
	private static void SingleDivide(BigInteger leftSide, BigInteger rightSide, out BigInteger quotient, out BigInteger remainder)
	{
		if (rightSide.IsZero)
		{
			throw new DivideByZeroException();
		}
		
		DigitsArray remainderDigits = new DigitsArray(leftSide.m_digits);
		remainderDigits.ResetDataUsed();
		
		int pos = remainderDigits.DataUsed - 1;
		ulong divisor = (ulong)rightSide.m_digits[0];
		ulong dividend = (ulong)remainderDigits[pos];
		
		DType[] result = new DType[leftSide.m_digits.Count];
		leftSide.m_digits.CopyTo(result, 0, result.Length);
		int resultPos = 0;
		
		if (dividend >= divisor)
		{
			result[resultPos++] = (DType)(dividend / divisor);
			remainderDigits[pos] = (DType)(dividend % divisor);
		}
		pos--;
		
		while (pos >= 0)
		{
			dividend = ((ulong)(remainderDigits[pos + 1]) << DigitsArray.DataSizeBits) + (ulong)remainderDigits[pos];
			result[resultPos++] = (DType)(dividend / divisor);
			remainderDigits[pos + 1] = 0;
			remainderDigits[pos--] = (DType)(dividend % divisor);
		}
		remainder = new BigInteger(remainderDigits);
		
		DigitsArray quotientDigits = new DigitsArray(resultPos + 1, resultPos);
		int j = 0;
		for (int i = quotientDigits.DataUsed - 1; i >= 0; i--, j++)
		{
			quotientDigits[j] = result[i];
		}
		quotient = new BigInteger(quotientDigits);
	}
Ejemplo n.º 23
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);
	}
Ejemplo n.º 24
0
	/// <summary>
	/// Multiply two BigIntegers returning the result.
	/// </summary>
	/// <remarks>
	/// See Knuth.
	/// </remarks>
	/// <param name="leftSide">A BigInteger.</param>
	/// <param name="rightSide">A BigInteger</param>
	/// <returns></returns>
	public static BigInteger operator * (BigInteger leftSide, BigInteger rightSide)
	{
		if (object.ReferenceEquals(leftSide, null))
		{
			throw new ArgumentNullException("leftSide");
		}
		if (object.ReferenceEquals(rightSide, null))
		{
			throw new ArgumentNullException("rightSide");
		}
		
		bool leftSideNeg = leftSide.IsNegative;
		bool rightSideNeg = rightSide.IsNegative;
		
		leftSide = Abs(leftSide);
		rightSide = Abs(rightSide);
		
		DigitsArray da = new DigitsArray(leftSide.m_digits.DataUsed + rightSide.m_digits.DataUsed);
		da.DataUsed = da.Count;
		
		for (int i = 0; i < leftSide.m_digits.DataUsed; i++)
		{
			ulong carry = 0;
			for (int j = 0, k = i; j < rightSide.m_digits.DataUsed; j++, k++)
			{
				ulong val = ((ulong)leftSide.m_digits[i] * (ulong)rightSide.m_digits[j]) + (ulong)da[k] + carry;
				
				da[k] = (DType)(val & DigitsArray.AllBits);
				carry = (val >> DigitsArray.DataSizeBits);
			}
			
			if (carry != 0)
			{
				da[i + rightSide.m_digits.DataUsed] = (DType)carry;
			}
		}
		
		//da.ResetDataUsed();
		BigInteger result = new BigInteger(da);
		return (leftSideNeg != rightSideNeg ? -result : result);
	}
Ejemplo n.º 25
0
	/// <summary>
	/// Negates the BigInteger, that is, if the BigInteger is negative return a positive BigInteger, and if the
	/// BigInteger is negative return the postive.
	/// </summary>
	/// <param name="leftSide">A BigInteger operand.</param>
	/// <returns>The value of the <paramref name="this" /> negated.</returns>
	public static BigInteger operator - (BigInteger leftSide)
	{
		if (object.ReferenceEquals(leftSide, null))
		{
			throw new ArgumentNullException("leftSide");
		}
		
		if (leftSide.IsZero)
		{
			return new BigInteger(0);
		}
		
		DigitsArray da = new DigitsArray(leftSide.m_digits.DataUsed + 1, leftSide.m_digits.DataUsed + 1);
		
		for (int i = 0; i < da.Count; i++)
		{
			da[i] = (DType)(~(leftSide.m_digits[i]));
		}
		
		// add one to result (1's complement + 1)
		bool carry = true;
		int index = 0;
		while (carry && index < da.Count)
		{
			long val = (long)da[index] + 1;
			da[index] = (DType)(val & DigitsArray.AllBits);
			carry = ((val >> DigitsArray.DataSizeBits) > 0);
			index++;
		}
		
		return new BigInteger(da);
	}
Ejemplo n.º 26
0
	internal DigitsArray(DigitsArray copyFrom)
	{
		Allocate(copyFrom.Count, copyFrom.DataUsed);
		Array.Copy(copyFrom.m_data, 0, m_data, 0, copyFrom.Count);
	}
Ejemplo n.º 27
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);
	}
Ejemplo n.º 28
0
	private void ConstructFrom(byte[] array, int offset, int length)
	{
		if (array == null)
		{
			throw new ArgumentNullException("array");
		}
		if (offset > array.Length || length > array.Length)
		{
			throw new ArgumentOutOfRangeException("offset");
		}
		if (length > array.Length || (offset + length) > array.Length)
		{
			throw new ArgumentOutOfRangeException("length");
		}
		
		int estSize = length / 4;
		int leftOver = length & 3;
		if (leftOver != 0)
		{
			++estSize;
		}
		
		m_digits = new DigitsArray(estSize + 1, 0); // alloc one extra since we can't init -'s from here.
		
		for (int i = offset + length - 1, j = 0; (i - offset) >= 3; i -= 4, j++)
		{
			m_digits[j] = (DType)((array[i - 3] << 24) + (array[i - 2] << 16) + (array[i - 1] <<  8) + array[i]);
			m_digits.DataUsed++;
		}
		
		DType accumulator = 0;
		for (int i = leftOver; i > 0; i--)
		{
			DType digit = array[offset + leftOver - i];
			digit = (digit << ((i - 1) * 8));
			accumulator |= digit;
		}
		m_digits[m_digits.DataUsed] = accumulator;
		
		m_digits.ResetDataUsed();
	}
Ejemplo n.º 29
0
 internal DigitsArray(DigitsArray copyFrom)
 {
     Allocate(copyFrom.Count, copyFrom.DataUsed);
     Array.Copy(copyFrom.m_data, 0, m_data, 0, copyFrom.Count);
 }
Ejemplo n.º 30
0
 /// <summary>
 /// Create a BigInteger with an integer value of 0.
 /// </summary>
 public BigInteger()
 {
     m_digits = new DigitsArray(1, 1);
 }
Ejemplo n.º 31
0
	public static BigInteger operator ^ (BigInteger leftSide, BigInteger rightSide)
	{
		int len = System.Math.Max(leftSide.m_digits.DataUsed, rightSide.m_digits.DataUsed);
		DigitsArray da = new DigitsArray(len, len);
		for (int idx = 0; idx < len; idx++)
		{
			da[idx] = (DType)(leftSide.m_digits[idx] ^ rightSide.m_digits[idx]);
		}
		return new BigInteger(da);
	}
Ejemplo n.º 32
0
	/// <summary>
	/// Adds two BigIntegers and returns a new BigInteger that represents the sum.
	/// </summary>
	/// <param name="leftSide">A BigInteger</param>
	/// <param name="rightSide">A BigInteger</param>
	/// <returns>The BigInteger result of adding <paramref name="leftSide" /> and <paramref name="rightSide" />.</returns>
	public static BigInteger operator + (BigInteger leftSide, BigInteger rightSide)
	{
		int size = System.Math.Max(leftSide.m_digits.DataUsed, rightSide.m_digits.DataUsed);
		DigitsArray da = new DigitsArray(size + 1);
		
		long carry = 0;
		for (int i = 0; i < da.Count; i++)
		{
			long sum = (long)leftSide.m_digits[i] + (long)rightSide.m_digits[i] + carry;
			carry  = (long)(sum >> DigitsArray.DataSizeBits);
			da[i] = (DType)(sum & DigitsArray.AllBits);
		}
		
		return new BigInteger(da);
	}