/// <summary> /// Constructs a BigInt from a UInt32 /// </summary> /// <param name="input"></param> /// <param name="precision"></param> public BigInt(Int64 input, PrecisionSpec precision) { Init(precision); if (input < 0) sign = true; digitArray[0] = (UInt32)(input & 0xffffffff); if (digitArray.Length >= 2) { if (input == Int64.MinValue) { digitArray[1] = 0x80000000; } else { digitArray[1] = (UInt32)((input >> 32) & 0x7fffffff); } } }
//*************** Utility Functions ************** /// <summary> /// Casts a BigInt to the new precision provided. /// Note: This will return the input if the precision already matches. /// </summary> /// <param name="input"></param> /// <param name="precision"></param> /// <returns></returns> public static BigInt CastToPrecision(BigInt input, PrecisionSpec precision) { if (input.pres == precision) return input; return new BigInt(input, precision); }
/// <summary> /// Constructs a BigInt from a UInt64 /// </summary> /// <param name="input"></param> /// <param name="precision"></param> public BigInt(UInt64 input, PrecisionSpec precision) { Init(precision); digitArray[0] = (UInt32)(input & 0xffffffff); if (digitArray.Length > 1) digitArray[1] = (UInt32)(input >> 32); }
/// <summary> /// Constructs a BigInt from an Int32 /// </summary> /// <param name="input"></param> /// <param name="precision"></param> public BigInt(Int32 input, PrecisionSpec precision) { Init(precision); if (input < 0) { sign = true; if (input == Int32.MinValue) { digitArray[0] = 0x80000000; } else { digitArray[0] = (UInt32)(-input); } } else { digitArray[0] = ((UInt32)input); } }
/// <summary> /// Constructs a bigint from the input, matching the new precision provided /// </summary> public BigInt(BigInt input, PrecisionSpec precision) { //Casts the input to the new precision. Init(precision); int Min = (input.digitArray.Length < digitArray.Length) ? input.digitArray.Length : digitArray.Length; for (int i = 0; i < Min; i++) { digitArray[i] = input.digitArray[i]; } sign = input.sign; }
/// <summary> /// Constructs a BigInt from a UInt32 /// </summary> /// <param name="input"></param> /// <param name="precision"></param> public BigInt(UInt32 input, PrecisionSpec precision) { Init(precision); digitArray[0] = input; }
/// <summary> /// Constructs a bigint from the string, with the desired precision, using base 10 /// </summary> /// <param name="init"></param> /// <param name="precision"></param> public BigInt(string init, PrecisionSpec precision) { InitFromString(init, precision, 10); }
/// <summary> /// Constructs a BigInt from a string, using the specified precision and base /// </summary> /// <param name="init"></param> /// <param name="precision"></param> /// <param name="numberBase"></param> public BigInt(string init, PrecisionSpec precision, int numberBase) { InitFromString(init, precision, numberBase); }
/// <summary> /// Constructor for copying length and precision /// </summary> /// <param name="inputToCopy">The BigInt to copy</param> /// <param name="precision">The precision of the new BigInt</param> /// <param name="bCopyLengthOnly">decides whether to copy the actual input, or just its digit length</param> /// <example><code>//Create an integer /// BigInt four = new BigInt(4, new PrecisionSpec(128, PrecisionSpec.BaseType.BIN)); /// /// //Pad four to double its usual number of digits (this does not affect the precision) /// four.Pad(); /// /// //Create a new, empty integer with matching precision, also padded to twice the usual length /// BigInt newCopy = new BigInt(four, four.Precision, true);</code></example> public BigInt(BigInt inputToCopy, PrecisionSpec precision, bool bCopyLengthOnly) { digitArray = new uint[inputToCopy.digitArray.Length]; workingSet = new uint[inputToCopy.digitArray.Length]; if (!bCopyLengthOnly) Array.Copy(inputToCopy.digitArray, digitArray, digitArray.Length); sign = inputToCopy.sign; pres = inputToCopy.pres; }
//*************** Constructors ****************** /// <summary> /// Constructs an empty BigInt to the desired precision. /// </summary> /// <param name="precision"></param> public BigInt(PrecisionSpec precision) { Init(precision); }
/// <summary> /// Initialises the BigInt from a string, given a base and precision /// </summary> /// <param name="init"></param> /// <param name="precision"></param> /// <param name="numberBase"></param> private void InitFromString(string init, PrecisionSpec precision, int numberBase) { PrecisionSpec test; if (numberBase == 2) { test = new PrecisionSpec(init.Length, PrecisionSpec.BaseType.BIN); } else if (numberBase == 8) { test = new PrecisionSpec(init.Length, PrecisionSpec.BaseType.OCT); } else if (numberBase == 10) { test = new PrecisionSpec(init.Length, PrecisionSpec.BaseType.DEC); } else if (numberBase == 16) { test = new PrecisionSpec(init.Length, PrecisionSpec.BaseType.HEX); } else { throw new ArgumentOutOfRangeException(); } //if (test.NumBits > precision.NumBits) precision = test; Init(precision); FromStringInt(init, numberBase); }
/// <summary> /// Initialises the BigInt to a desired decimal precision /// </summary> /// <param name="precision"></param> private void Init(PrecisionSpec precision) { int numDigits = GetRequiredDigitsForPrecision(precision); digitArray = new uint[numDigits]; workingSet = new uint[numDigits]; pres = precision; }
/// <summary> /// Returns the length of the BigInt in 32-bit words for a given decimal precision /// </summary> /// <param name="precision"></param> /// <returns></returns> private static int GetRequiredDigitsForPrecision(PrecisionSpec precision) { int bits = precision.NumBits; return ((bits - 1) >> 5) + 1; }