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; }
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); }