/// <summary> /// Returns this BigInteger as an double value. /// <para>If this is too big to be represented as an double, then Double.POSITIVE_INFINITY or /// Double.NEGATIVE_INFINITY} is returned.</para> /// </summary> /// /// <param name="Value">The value to convert</param> /// /// <returns>Returns a BigInteger as a double value</returns> /// /// <remarks> /// Note, that not all integers x in the range [-Double.MAX_VALUE, Double.MAX_VALUE] can be represented as a double. /// The double representation has a mantissa of length 53. For example, 2^53+1 = 9007199254740993 is returned as double 9007199254740992.0. /// </remarks> internal static double BigInteger2Double(BigInteger Value) { // val.bitLength() < 64 if ((Value._numberLength < 2) || ((Value._numberLength == 2) && (Value._digits[1] > 0))) { return(Value.ToInt64()); } // val.bitLength() >= 33 * 32 > 1024 if (Value._numberLength > 32) { return((Value._sign > 0) ? Double.PositiveInfinity : Double.NegativeInfinity); } int bitLen = Value.Abs().BitLength; long exponent = bitLen - 1; int delta = bitLen - 54; // We need 54 top bits from this, the 53th bit is always 1 in lVal. long lVal = Value.Abs().ShiftRight(delta).ToInt64(); // Take 53 bits from lVal to mantissa. The least significant bit is needed for rounding. long mantissa = lVal & 0x1FFFFFFFFFFFFFL; if (exponent == 1023) { if (mantissa == 0X1FFFFFFFFFFFFFL) { return((Value._sign > 0) ? Double.PositiveInfinity : Double.NegativeInfinity); } if (mantissa == 0x1FFFFFFFFFFFFEL) { return((Value._sign > 0) ? Double.MaxValue : -Double.MaxValue); } } // Round the mantissa if (((mantissa & 1) == 1) && (((mantissa & 2) == 2) || BitLevel.NonZeroDroppedBits(delta, Value._digits))) { mantissa += 2; } mantissa >>= 1; // drop the rounding bit // long resSign = (val.sign < 0) ? 0x8000000000000000L : 0; long resSign = (Value._sign < 0) ? Int64.MinValue : 0; exponent = ((1023 + exponent) << 52) & 0x7FF0000000000000L; long result = resSign | exponent | mantissa; return(BitConverter.Int64BitsToDouble(result)); }