/// <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> /// Construct a BigFloat from a double-precision floating point number /// </summary> /// <param name="value"></param> /// <param name="mantissaPrec"></param> public BigFloat(double value, PrecisionSpec mantissaPrec) { if (value == 0.0) { Init(mantissaPrec); return; } bool sign = (value < 0) ? true : false; long bits = BitConverter.DoubleToInt64Bits(value); // Note that the shift is sign-extended, hence the test against -1 not 1 int valueExponent = (int)((bits >> 52) & 0x7ffL); long valueMantissa = bits & 0xfffffffffffffL; //The mantissa is stored with the top bit implied. valueMantissa = valueMantissa | 0x10000000000000L; //The exponent is biased by 1023. exponent = valueExponent - 1023; //Round the number of bits to the nearest word. int mbWords = ((mantissaPrec.NumBits) >> 5); if ((mantissaPrec.NumBits & 31) != 0) mbWords++; int newManBits = mbWords << 5; mantissa = new BigInt(new PrecisionSpec(newManBits, PrecisionSpec.BaseType.BIN)); //scratch = new BigInt(new PrecisionSpec(newManBits, PrecisionSpec.BaseType.BIN)); if (newManBits >= 64) { //The mantissa is 53 bits now, so add 11 to put it in the right place. mantissa.SetHighDigits(valueMantissa << 11); } else { //To get the top word of the mantissa, shift up by 11 and down by 32 = down by 21 mantissa.SetHighDigit((uint)(valueMantissa >> 21)); } mantissa.Sign = sign; }
/// <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; }