public static DoubleComponents Decompose(this double d)
        {
            // See http://msdn.microsoft.com/en-us/library/aa691146(VS.71).aspx
            // and Steve Hollasch's http://steve.hollasch.net/cgindex/coding/ieeefloat.html
            // and PremK's http://blogs.msdn.com/b/premk/archive/2006/02/25/539198.aspx

            var result = new DoubleComponents { Datum = d };

            long bits = BitConverter.DoubleToInt64Bits(d);
            bool fNegative = (bits < 0);
            int exponent = (int)((bits >> 52) & 0x7ffL);
            long mantissa = (bits & 0xfffffffffffffL);

            result.Negative = fNegative;
            result.RawExponentInt = exponent;
            result.RawMantissaLong = mantissa;

            if (exponent == 0x7ffL && mantissa != 0)
            {
                Contract.Assert(double.IsNaN(d));

                // The number is an NaN. Client must interpret.
                result.IsNaN = true;
                return result;
            }

            // The first bit of the mathematical mantissaBits is always 1, and it is not
            // represented in the stored mantissaBits bits. The following logic accounts for
            // this and restores the mantissaBits to its mathematical value.

            if (exponent == 0)
            {
                if (mantissa == 0)
                {
                    // Returning either +0 or -0.
                    return result;
                }
                // Denormalized: A fool-proof detector for denormals is a zero exponentBits.
                // Mantissae for denormals do not have an assumed leading 1-bit. Bump the
                // exponentBits by one so that when we re-bias it by -1023, we have actually
                // brought it back down by -1022, the way it should be. This increment merges
                // the logic for normals and denormals.
                exponent++;
            }
            else
            {
                // Normalized: radix point (the binary point) is after the first non-zero digit (bit).
                // Or-in the *assumed* leading 1 bit to restore the mathematical mantissaBits.
                mantissa = mantissa | (1L << 52);
            }

            // Re-bias the exponentBits by the IEEE 1023, which treats the mathematical mantissaBits
            // as a pure fraction, minus another 52, because we treat the mathematical mantissaBits
            // as a pure integer.
            exponent -= 1075;

            // Produce form with lowest possible whole-number mantissaBits.
            while ((mantissa & 1) == 0)
            {
                mantissa >>= 1;
                exponent++;
            }

            result.MathematicalBase2Exponent = exponent;
            result.MathematicalBase2Mantissa = mantissa;
            return result;
        }
Esempio n. 2
0
        public static DoubleComponents Decompose(this double d)
        {
            // See http://msdn.microsoft.com/en-us/library/aa691146(VS.71).aspx
            // and Steve Hollasch's http://steve.hollasch.net/cgindex/coding/ieeefloat.html
            // and PremK's http://blogs.msdn.com/b/premk/archive/2006/02/25/539198.aspx

            var result = new DoubleComponents {
                Datum = d
            };

            long bits      = BitConverter.DoubleToInt64Bits(d);
            bool fNegative = (bits < 0);
            int  exponent  = (int)((bits >> 52) & 0x7ffL);
            long mantissa  = (bits & 0xfffffffffffffL);

            result.Negative        = fNegative;
            result.RawExponentInt  = exponent;
            result.RawMantissaLong = mantissa;

            if (exponent == 0x7ffL && mantissa != 0)
            {
                Contract.Assert(double.IsNaN(d));

                // The number is an NaN. Client must interpret.
                result.IsNaN = true;
                return(result);
            }

            // The first bit of the mathematical mantissaBits is always 1, and it is not
            // represented in the stored mantissaBits bits. The following logic accounts for
            // this and restores the mantissaBits to its mathematical value.

            if (exponent == 0)
            {
                if (mantissa == 0)
                {
                    // Returning either +0 or -0.
                    return(result);
                }
                // Denormalized: A fool-proof detector for denormals is a zero exponentBits.
                // Mantissae for denormals do not have an assumed leading 1-bit. Bump the
                // exponentBits by one so that when we re-bias it by -1023, we have actually
                // brought it back down by -1022, the way it should be. This increment merges
                // the logic for normals and denormals.
                exponent++;
            }
            else
            {
                // Normalized: radix point (the binary point) is after the first non-zero digit (bit).
                // Or-in the *assumed* leading 1 bit to restore the mathematical mantissaBits.
                mantissa = mantissa | (1L << 52);
            }

            // Re-bias the exponentBits by the IEEE 1023, which treats the mathematical mantissaBits
            // as a pure fraction, minus another 52, because we treat the mathematical mantissaBits
            // as a pure integer.
            exponent -= 1075;

            // Produce form with lowest possible whole-number mantissaBits.
            while ((mantissa & 1) == 0)
            {
                mantissa >>= 1;
                exponent++;
            }

            result.MathematicalBase2Exponent = exponent;
            result.MathematicalBase2Mantissa = mantissa;
            return(result);
        }