If you reflect over WindowsBase.dll > MS.Internal.DoubleUtil.AreClose(...)
you'll get the following code:
public static bool AreClose(double value1, double value2)
{
if (value1 == value2)
{
return true;
}
double num2 = ((Math.Abs(value1) + Math.Abs(value2)) + 10.0) * 2.2204460492503131E-16;
double num = value1 - value2;
return ((-num2 < num) && (num2 > num));
}
I'm trying to understand two different things:
Where did they come up with the formula for num2? I guess I just don't understand the significance of first adding the value of 10.0
and secondly multiplying all the results by this the number 2.2204460492503131E-16
. Anyone know why this is the formula used?
What is the point of the return statement there? It seems that by default if num2 greater than num than the negated value of num2 should be less than num. Maybe I'm missing something here, but it seems redundant. To me it's like checking if 5 is larger than 3 and if -5 is less than 3 (as an example).
This appears to be a "tolerance" value that's based on the magnitude of the numbers being compared. Note that due to how floating point numbers are represented, the smallest representable difference between numbers with an exponent of 0 is 2-53 or approximately 1.11022 × 10-16. (See unit in the last place and floating point on Wikipedia.) The constant here is exactly two times that value, so it allows for small rounding errors that have accumulated during computations.
If you reorder the parameters in the conditionals, and then rename num2
to tolerance
and num
to diff
, it should become clear.
Viz.:
return ((-num2 < num) && (num2 > num));
return ((num > -num2) && (num < num2));
return ((diff > -tolerance) && (diff < tolerance));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With