/// <summary> /// Constructs a BigFloat from a 64-bit unsigned integer /// </summary> /// <param name="value"></param> /// <param name="mantissaPrec"></param> public BigFloat(UInt64 value, PrecisionSpec mantissaPrec) { int mbWords = ((mantissaPrec.NumBits) >> 5); if ((mantissaPrec.NumBits & 31) != 0) mbWords++; int newManBits = mbWords << 5; //For efficiency, we just use a 32-bit exponent exponent = 0; int bit = BigInt.GetMSB(value); mantissa = new BigInt(value, new PrecisionSpec(newManBits, PrecisionSpec.BaseType.BIN)); //scratch = new BigInt(mantissa.Precision); int shift = mantissa.Precision.NumBits - (bit + 1); if (shift > 0) { mantissa.LSH(shift); } else { mantissa.SetHighDigit((uint)(value >> (-shift))); } exponent = bit; }
/// <summary> /// Constructs a BigFloat from a 64-bit integer /// </summary> /// <param name="value"></param> /// <param name="mantissaPrec"></param> public BigFloat(Int64 value, PrecisionSpec mantissaPrec) { int mbWords = ((mantissaPrec.NumBits) >> 5); if ((mantissaPrec.NumBits & 31) != 0) mbWords++; int newManBits = mbWords << 5; //For efficiency, we just use a 32-bit exponent exponent = 0; UInt64 uValue; if (value < 0) { if (value == Int64.MinValue) { uValue = 0x80000000; } else { uValue = (UInt64)(-value); } } else { uValue = (UInt64)value; } mantissa = new BigInt(value, new PrecisionSpec(newManBits, PrecisionSpec.BaseType.BIN)); //scratch = new BigInt(new PrecisionSpec(newManBits, PrecisionSpec.BaseType.BIN)); int bit = BigInt.GetMSB(uValue); if (bit == -1) return; int shift = mantissa.Precision.NumBits - (bit + 1); if (shift > 0) { mantissa.LSH(shift); } else { mantissa.SetHighDigit((uint)(uValue >> (-shift))); } exponent = bit; }
/// <summary> /// Shifts and optionally precision-extends the arguments to prepare for Div_32 /// </summary> /// <param name="n1"></param> /// <param name="n2"></param> private static int MakeSafeDiv(BigInt n1, BigInt n2) { int shift = n2.GetDivBitshift(); int n1MSD = n1.GetMSD(); uint temp = n1.digitArray[n1MSD]; if (n1MSD == n1.digitArray.Length - 1 && ((temp << shift) >> shift) != n1.digitArray[n1MSD]) { //Precision-extend n1 and n2 if necessary int digits = n1.digitArray.Length; n1.SetNumDigits(digits + 1); n2.SetNumDigits(digits + 1); } //Logical left-shift n1 and n2 n1.LSH(shift); n2.LSH(shift); return shift; }
/// <summary> /// Constructs a big float from a UInt32 to the required precision /// </summary> /// <param name="value"></param> /// <param name="mantissaPrec"></param> public BigFloat(UInt32 value, PrecisionSpec mantissaPrec) { int mbWords = ((mantissaPrec.NumBits) >> 5); if ((mantissaPrec.NumBits & 31) != 0) mbWords++; int newManBits = mbWords << 5; //For efficiency, we just use a 32-bit exponent exponent = 0; mantissa = new BigInt(value, new PrecisionSpec(newManBits, PrecisionSpec.BaseType.BIN)); //scratch = new BigInt(mantissa.Precision); int bit = BigInt.GetMSB(value); if (bit == -1) return; int shift = mantissa.Precision.NumBits - (bit + 1); mantissa.LSH(shift); exponent = bit; }
/// <summary> /// The left-shift operator /// </summary> public static BigInt operator <<(BigInt n1, int n2) { BigInt res = new BigInt(n1); res.LSH(n2); return res; }