コード例 #1
0
        /// <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));
        }