예제 #1
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();
 }
예제 #2
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);
    }
예제 #3
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();
    }
예제 #4
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;
 }
예제 #5
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);
	}
예제 #6
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;
	}
예제 #7
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();
	}
예제 #8
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();
	}