コード例 #1
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;
		}
コード例 #2
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 Add(BigInteger leftSide, BigInteger rightSide)
		{
			return leftSide - rightSide;
		}
コード例 #3
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);
		}
コード例 #4
0
 /// <summary>
 /// Converts B36 encoded string into Hexadecimal EPC
 /// </summary>
 /// <param name="b36"></param>
 /// <returns>Hex string</returns>
 public static String ConvertBase36ToHex(String b36)
 {
     if (b36.Length > 0)
     {
         StringBuilder sb = new StringBuilder(b36.ToUpper());
         char[] charArray = sb.ToString().ToCharArray();
         Array.Reverse(charArray);
         BigInteger big = new BigInteger(new string(charArray), 36);
         if (b36.Length != big.ToHexString().Length)
         {
             return big.ToHexString().TrimStart('0');
         }
         else
         {
             return big.ToHexString();
         }
     }
     else
     {
         return string.Empty;
     }
 }
コード例 #5
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);
		}
コード例 #6
0
		/// <summary>
		/// Divide a BigInteger by another BigInteger and returning the result.
		/// </summary>
		/// <param name="leftSide">A BigInteger divisor.</param>
		/// <param name="rightSide">A BigInteger dividend.</param>
		/// <returns>The BigInteger result.</returns>
		public static BigInteger Divide(BigInteger leftSide, BigInteger rightSide)
		{
			return leftSide / rightSide;
		}
コード例 #7
0
		public static BigInteger LeftShift(BigInteger leftSide, int shiftCount)
		{
			return leftSide << shiftCount;
		}
コード例 #8
0
		/// <summary>
		/// Decrements the BigInteger operand by 1.
		/// </summary>
		/// <param name="leftSide">The BigInteger operand.</param>
		/// <returns>The value of the <paramref name="leftSide" /> decremented by 1.</returns>
		public static BigInteger Decrement(BigInteger leftSide)
		{
			return (leftSide - 1);
		}
コード例 #9
0
		public static BigInteger Xor(BigInteger leftSide, BigInteger rightSide)
		{
			return leftSide ^ rightSide;
		}
コード例 #10
0
		public static BigInteger OnesComplement(BigInteger leftSide)
		{
			return ~leftSide;
		}
コード例 #11
0
		public static BigInteger BitwiseOr(BigInteger leftSide, BigInteger rightSide)
		{
			return leftSide | rightSide;
		}
コード例 #12
0
		public static BigInteger BitwiseAnd(BigInteger leftSide, BigInteger rightSide)
		{
			return leftSide & rightSide;
		}
コード例 #13
0
		/// <summary>
		/// Perform the modulus of a BigInteger with another BigInteger and return the result.
		/// </summary>
		/// <param name="leftSide">A BigInteger divisor.</param>
		/// <param name="rightSide">A BigInteger dividend.</param>
		/// <returns>The BigInteger result.</returns>
		public static BigInteger Modulus(BigInteger leftSide, BigInteger rightSide)
		{
			return leftSide % rightSide;
		}
コード例 #14
0
		/// <summary>
		/// Increments the BigInteger operand by 1.
		/// </summary>
		/// <param name="leftSide">The BigInteger operand.</param>
		/// <returns>The value of <paramref name="leftSide" /> incremented by 1.</returns>
		public static BigInteger Increment(BigInteger leftSide)
		{
			return (leftSide + 1);
		}
コード例 #15
0
		public static BigInteger RightShift(BigInteger leftSide, int shiftCount)
		{
			if (leftSide == null)
			{
				throw new ArgumentNullException("leftSide");
			}

			return leftSide >> shiftCount;
		}
コード例 #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 Subtract(BigInteger leftSide, BigInteger rightSide)
		{
			return leftSide - rightSide;
		}
コード例 #17
0
		/// <summary>
		/// Compare this instance to a specified object and returns indication of their relative value.
		/// </summary>
		/// <param name="value">An object to compare, or a null reference (<b>Nothing</b> in Visual Basic).</param>
		/// <returns>A signed number indicating the relative value of this instance and <i>value</i>.
		/// <list type="table">
		///		<listheader>
		///			<term>Return Value</term>
		///			<description>Description</description>
		///		</listheader>
		///		<item>
		///			<term>Less than zero</term>
		///			<description>This instance is less than <i>value</i>.</description>
		///		</item>
		///		<item>
		///			<term>Zero</term>
		///			<description>This instance is equal to <i>value</i>.</description>
		///		</item>
		///		<item>
		///			<term>Greater than zero</term>
		///			<description>
		///				This instance is greater than <i>value</i>. 
		///				<para>-or-</para>
		///				<i>value</i> is a null reference (<b>Nothing</b> in Visual Basic).
		///			</description>
		///		</item>
		/// </list>
		/// </returns>
		public int CompareTo(BigInteger value)
		{
			return Compare(this, value);
		}
コード例 #18
0
		/// <summary>
		/// Creates a BigInteger absolute value of the operand.
		/// </summary>
		/// <param name="leftSide">A BigInteger.</param>
		/// <returns>A BigInteger that represents the absolute value of <paramref name="leftSide" />.</returns>
		public static BigInteger Abs(BigInteger leftSide)
		{
			if (object.ReferenceEquals(leftSide, null))
			{
				throw new ArgumentNullException("leftSide");
			}
			if (leftSide.IsNegative)
			{
				return -leftSide;
			}
			return leftSide;
		}
コード例 #19
0
		/// <summary>
		/// Compare two objects and return an indication of their relative value.
		/// </summary>
		/// <param name="leftSide">An object to compare, or a null reference (<b>Nothing</b> in Visual Basic).</param>
		/// <param name="rightSide">An object to compare, or a null reference (<b>Nothing</b> in Visual Basic).</param>
		/// <returns>A signed number indicating the relative value of this instance and <i>value</i>.
		/// <list type="table">
		///		<listheader>
		///			<term>Return Value</term>
		///			<description>Description</description>
		///		</listheader>
		///		<item>
		///			<term>Less than zero</term>
		///			<description>This instance is less than <i>value</i>.</description>
		///		</item>
		///		<item>
		///			<term>Zero</term>
		///			<description>This instance is equal to <i>value</i>.</description>
		///		</item>
		///		<item>
		///			<term>Greater than zero</term>
		///			<description>
		///				This instance is greater than <i>value</i>. 
		///				<para>-or-</para>
		///				<i>value</i> is a null reference (<b>Nothing</b> in Visual Basic).
		///			</description>
		///		</item>
		/// </list>
		/// </returns>
		public static int Compare(BigInteger leftSide, BigInteger rightSide)
		{
			if (object.ReferenceEquals(leftSide, rightSide))
			{
				return 0;
			}

			if (object.ReferenceEquals(leftSide, null))
			{
				throw new ArgumentNullException("leftSide");
			}

			if (object.ReferenceEquals(rightSide, null))
			{
				throw new ArgumentNullException("rightSide");
			}

			if (leftSide > rightSide) return 1;
			if (leftSide == rightSide) return 0;
			return -1;
		}
コード例 #20
0
		/// <summary>
		/// Multiply two BigIntegers returning the result.
		/// </summary>
		/// <param name="leftSide">A BigInteger.</param>
		/// <param name="rightSide">A BigInteger</param>
		/// <returns></returns>
		public static BigInteger Multiply(BigInteger leftSide, BigInteger rightSide)
		{
			return leftSide * rightSide;
		}
コード例 #21
0
		/// <summary>
		/// Converts the numeric value of this instance to its equivalent string representation in specified base.
		/// </summary>
		/// <param name="radix">Int radix between 2 and 36</param>
		/// <returns>A string.</returns>
		public string ToString(int radix)
		{
			if (radix < 2 || radix > 36)
			{
				throw new ArgumentOutOfRangeException("radix");
			}

			if (IsZero)
			{
				return "0";
			}

			BigInteger a = this;
			bool negative = a.IsNegative;
			a = Abs(this);

			BigInteger quotient;
			BigInteger remainder;
			BigInteger biRadix = new BigInteger(radix);

			const string charSet = "0123456789abcdefghijklmnopqrstuvwxyz";
			System.Collections.ArrayList al = new System.Collections.ArrayList();
			while (a.m_digits.DataUsed > 1 || (a.m_digits.DataUsed == 1 && a.m_digits[0] != 0))
			{
				Divide(a, biRadix, out quotient, out remainder);
				al.Insert(0, charSet[(int)remainder.m_digits[0]]);
				a = quotient;
			}

			string result = new String((char[])al.ToArray(typeof(char)));
			if (radix == 10 && negative)
			{
				return "-" + result;
			}

			return result;
		}
コード例 #22
0
		private static void Divide(BigInteger leftSide, BigInteger rightSide, out BigInteger quotient, out BigInteger remainder)
		{
			if (leftSide.IsZero)
			{
				quotient = new BigInteger();
				remainder = new BigInteger();
				return;
			}

			if (rightSide.m_digits.DataUsed == 1)
			{
				SingleDivide(leftSide, rightSide, out quotient, out remainder);
			}
			else
			{
				MultiDivide(leftSide, rightSide, out quotient, out remainder);
			}
		}
コード例 #23
0
		/// <summary>
		/// Returns BigInteger as System.UInt64 if possible.
		/// </summary>
		/// <param name="value"></param>
		/// <returns></returns>
		/// <exception cref="System.Exception">When BigInteger is too large to fit into System.UInt64</exception>
		public static ulong ToUInt64(BigInteger value)
		{
			if (object.ReferenceEquals(value, null))
			{
				throw new ArgumentNullException("value");
			}
			return System.UInt64.Parse(value.ToString(), System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.CurrentCulture);
		}
コード例 #24
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);
		}
コード例 #25
0
 /// <summary>
 /// Converts Hexadecimal EPC into reversed B36 encoded string
 /// </summary>
 /// <param name="hex"></param>
 /// <returns></returns>
 public static String ConvertHexToBase36(String hex)
 {
     if (hex.Length > 0)
     {
         BigInteger big = new BigInteger(hex.ToUpper(), 16);
         StringBuilder sb = new StringBuilder(big.ToString(36));
         char[] charArray = sb.ToString().ToCharArray();
         Array.Reverse(charArray);
         return new string(charArray).ToUpper();
     }
     else
     {
         return string.Empty;
     }
 }