Exemple #1
0
        /// <summary>
        /// Compares two floating point values within a specified tolerance in ULPs.
        /// </summary>
        /// <param name="x">One floating point value to be compared.</param>
        /// <param name="y">Other floating point value to be compared.</param>
        /// <param name="tolerance">The tolerance for equality in terms of ULPs.</param>
        /// <param name="difference">The difference between the values in terms of ULPs.</param>
        /// <returns>0 if <paramref name="x"/> = <paramref name="y"/> &#177; <paramref name="tolerance"/> ULPs; +1 if x &gt; y + tolerance ULPs; -1 if x &lt; y - tolerance ULPs.</returns>
        /// <remarks>
        /// <list>
        /// <item> 0 if x = y &#177; tolerance ULPs</item>
        /// <item>+1 if x &gt; y + tolerance ULPs</item>
        /// <item>-1 if x &lt; y - tolerance ULPs</item>
        /// </list>
        /// </remarks>
        /// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="tolerance"/> is negative or in excess of 2<sup>51</sup> (the limit of the significand in a double-precision floating point value).</exception>
        public static int Compare(double x, double y, long tolerance, out long difference)
        {
            // Make sure tolerance is non-negative and small enough that the
            // default NAN won't compare as equal to anything.
            const long maxSignificand = 2L * 1024 * 1024 * 1024 * 1024 * 1024;   // double-precision values has a 51-bit significand

            if (tolerance < 0 || tolerance >= maxSignificand)
            {
                throw new ArgumentOutOfRangeException("tolerance", "Tolerance must be in the range [0,2\u2075\u00B9)");
            }

            // Reinterpret double bits as sign-magnitude long integers.
            long xi = DoubleBitReinterpreter.Convert(x);
            long yi = DoubleBitReinterpreter.Convert(y);

            // Convert from sign-magnitude to two's complement form,
            // by subtracting from 0x8000000000000000.
            if (xi < 0)
            {
                xi = long.MinValue - xi;
            }
            if (yi < 0)
            {
                yi = long.MinValue - yi;
            }

            // How many epsilons apart?
            difference = xi - yi;

            // Is the difference outside our tolerance?
            if (xi > yi + tolerance)
            {
                return(+1);
            }
            if (xi < yi - tolerance)
            {
                return(-1);
            }
            else
            {
                return(0);
            }
        }
Exemple #2
0
 internal static double Convert(long value)
 {
     return(DoubleBitReinterpreter.Convert(value));
 }
Exemple #3
0
 internal static long Convert(double value)
 {
     return(DoubleBitReinterpreter.Convert(value));
 }