3

The documentation for Double.Equals contains a useful method

public static bool HasMinimalDifference(double value1, double value2, int units)
{
    long lValue1 = BitConverter.DoubleToInt64Bits(value1);
    long lValue2 = BitConverter.DoubleToInt64Bits(value2);

    // If the signs are different, return false except for +0 and -0.
    if ((lValue1 >> 63) != (lValue2 >> 63))
    {
        if (value1 == value2)
            return true;

        return false;
    }

    long diff = Math.Abs(lValue1 - lValue2);

    if (diff <= (long)units)
        return true;

    return false;
}

which seems to be the recommended way of testing for the "equality" of two double values.

However, try as I might I cannot work out the purpose of the third argument, units. In the example given, a value of 1 is passed, and no other explanation for its existence is given.

Can anyone clarify this?

fubo
  • 44,811
  • 17
  • 103
  • 137
Dave
  • 3,429
  • 2
  • 26
  • 29
  • I think the answer to your question is right there: *"The difference between the integer representation of two floating-point values indicates the number of possible floating-point values that separates them. For example, the difference between 0.0 and Epsilon is 1, because Epsilon is the smallest representable value when working with a Double whose value is zero."* – Filburt Mar 20 '18 at 12:16
  • See [this answer](https://softwareengineering.stackexchange.com/a/233274) for more explanation of the `units` parameter. – NightOwl888 Mar 20 '18 at 12:18
  • I'm not so sure I agree that that method is useful. It has a special exception to handle negative zero, but that special exception seems somewhat poorly thought out: it means `HasMinimalDifference(0.0, 1E-323, 2)` returns `true`, `HasMinimalDifference(-0.0, 1E-323, 200000)` returns `false`, even though `0.0 == -0.0`. –  Mar 20 '18 at 12:30
  • Hmya, this method seems mostly designed to get people off the support telephone. It is a tweak parameter, there are about 3 units in one significant decimal digit, starting from the 16th. 1 / log10(2) = 3.3 to be more exact, double has log10(pow(2, 53)) = 15.9 significant digits at best. [Look here](https://stackoverflow.com/a/2411661/17034) for something a bit less hacky. – Hans Passant Mar 20 '18 at 13:33

0 Answers0