Beispiel #1
0
        /// <summary>
        /// Returns a new instance BigInteger structure from a 64-bit double precision floating
        /// point value.
        /// </summary>
        /// <param name="value"> A 64-bit double precision floating point value. </param>
        /// <returns> The corresponding BigInteger value. </returns>
        public double ToDouble()
        {
            // Special case: zero.
            if (this.wordCount == 1 && this.bits[0] == 0)
            {
                return(0.0);
            }

            // Get the number of bits in the BigInteger.
            var bitCount = this.BitCount;

            // The top 53 bits can be packed into the double (the top-most bit is implied).
            var   temp       = BigInteger.RightShift(this, bitCount - 53);
            ulong doubleBits = (((ulong)temp.bits[1] << 32) | temp.bits[0]) & 0xFFFFFFFFFFFFF;

            // Base-2 exponent is however much we shifted, plus 52 (because the decimal point is
            // effectively at the 52nd bit), plus 1023 (the bias).
            doubleBits |= (ulong)(bitCount - 53 + 52 + 1023) << 52;

            // Handle the sign bit.
            if (this.sign == -1)
            {
                doubleBits |= (ulong)1 << 63;
            }

            // Convert the bit representation to a double.
            return(XBitConverter.Int64BitsToDouble((long)doubleBits));
        }
Beispiel #2
0
        /// <summary>
        /// Calculates the minimum increment that creates a number distinct from the value that was
        /// provided.  The error for the number is plus or minus half the result of this method
        /// (note that the number returned by this method may be so small that dividing it by two
        /// produces zero).
        /// </summary>
        /// <param name="value"> The number to calculate an error value for. </param>
        /// <returns> The minimum increment that creates a number distinct from the value that was
        /// provided. </returns>
        private static double CalculateError(double value)
        {
            long bits = XBitConverter.DoubleToInt64Bits(value);

            // Extract the base-2 exponent.
            var base2Exponent = (int)((bits & 0x7FF0000000000000) >> 52);

            // Handle denormals.
            if (base2Exponent == 0)
            {
                return(double.Epsilon);
            }

            // Handle very small numbers.
            if (base2Exponent < 53)
            {
                return(XBitConverter.Int64BitsToDouble(1L << (base2Exponent - 1)));
            }

            // Subtract 52 from the exponent to get the error (52 is the number of bits in the mantissa).
            return(XBitConverter.Int64BitsToDouble((long)(base2Exponent - 52) << 52));
        }
Beispiel #3
0
 /// <summary>
 /// Adds ULPs (units in the last place) to the given double-precision number.
 /// </summary>
 /// <param name="value"> The value to modify. </param>
 /// <param name="ulps"> The number of ULPs to add.  Can be negative. </param>
 /// <returns> The modified number. </returns>
 private static double AddUlps(double value, int ulps)
 {
     // Note: overflow or underflow in mantissa carries over to the exponent.
     // Overflow or underflow in exponent produces infinity or zero.
     return(XBitConverter.Int64BitsToDouble(XBitConverter.DoubleToInt64Bits(value) + ulps));
 }