public static void ThrowIfUndefined(this BigNum value) { value.ThrowIfNullArg(); if (value.IsUndefined) { throw new InvalidOperationException("Value is undefined."); } }
public static BigNum Pow2(int exponent) { if (exponent < 0) { var one = new BigNum("1"); return(one / Pow2(-exponent)); } return(new BigNum(BigInteger.Pow(2, exponent).ToString())); }
private unsafe void ParseDouble(double value) { if (double.IsNegativeInfinity(value) || double.IsPositiveInfinity(value) || double.IsNaN(value)) { IsUndefined = true; _exponent = 0; _number = 0; } else { ulong bits = ((ulong *)&value)[0]; /* Determine whether or not the number is negative. */ bool isNegative = (int)((bits >> 63) & 0x1) != 0; /* Grab the exponent portion of the double (63 - 52 = 11 bits max) */ int shift = (int)((int)(bits >> 52) & DoubleExponentMask); shift -= DoubleExponentShiftValue; /* Grab the exponent portion */ ulong fraction = bits & DoubleFractionMask; if (shift != 0) { fraction |= (ulong)BigInteger.Pow(2, 52); } BigNum fractionBigNum = new BigNum(fraction.ToString()); fractionBigNum *= Pow2(shift - 52); _number = fractionBigNum._number; _exponent = fractionBigNum._exponent; if (fraction == 0 && shift == 0) { _number = 1; } if (isNegative) { _number *= -1; } } }
/// <summary> /// Determines whether or not <seealso cref="double"/>.ToString(), for the specified value, generates an /// exact representation of the stored value. /// </summary> /// <param name="value">The <seealso cref="double"/> to check.</param> /// <returns>True if the <seealso cref="double"/>'s .ToString() is exact; false otherwise.</returns> public static bool IsToStringCorrect(double value) { BigNum doubleVersion = new BigNum(value, false); BigNum stringVersion = new BigNum(value, true); var doubleVersionString = doubleVersion.ToString(); var stringVersrionString = stringVersion.ToString(); if (doubleVersionString.Length < stringVersrionString.Length) { return(false); } for (int i = 0; i < doubleVersionString.Length; i++) { if (doubleVersionString[i] != stringVersrionString[i]) { return(false); } } return(true); }