如果您反映WindowsBase.dll > MS.Internal.DoubleUtil.AreClose(...)
,您将获得以下代码:
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));
}
我试图理解两件不同的事情:
10.0
值的意义,其次将所有结果乘以2.2204460492503131E-16
。任何人都知道为什么这是使用的公式?num2
重命名为tolerance
并将num
重命名为diff
,它应该变得清晰。见:
return ((-num2 < num) && (num2 > num));
return ((num > -num2) && (num < num2));
return ((diff > -tolerance) && (diff < tolerance));
评论应该有助于理解这个方法:)
/// <summary>
/// AreClose - Returns whether or not two doubles are "close". That is, whether or
/// not they are within epsilon of each other. Note that this epsilon is proportional
/// to the numbers themselves to that AreClose survives scalar multiplication.
/// There are plenty of ways for this to return false even for numbers which
/// are theoretically identical, so no code calling this should fail to work if this
/// returns false. This is important enough to repeat:
/// NB: NO CODE CALLING THIS FUNCTION SHOULD DEPEND ON ACCURATE RESULTS - this should be
/// used for optimizations *only*.
/// </summary>
/// <returns>
/// bool - the result of the AreClose comparision.
/// </returns>
/// <param name="value1"> The first double to compare. </param>
/// <param name="value2"> The second double to compare. </param>
public static bool AreClose(double value1, double value2)
{
// in case they are Infinities (then epsilon check does not work)
if (value1 == value2)
{
return true;
}
// This computes (|value1-value2| / (|value1| + |value2| + 10.0)) < DBL_EPSILON
double eps = (Math.Abs(value1) + Math.Abs(value2) + 10.0) * DBL_EPSILON;
double delta = value1 - value2;
return (-eps < delta) && (eps > delta);
}
更新
而这里的“神秘”价值DBL_EPSILON
// Const values come from sdk\inc\crt\float.h
internal const double DBL_EPSILON = 2.2204460492503131e-016; /* smallest such that 1.0+DBL_EPSILON != 1.0 */
在谷歌搜索该号码引导我到这个页面http://en.m.wikipedia.org/wiki/Machine_epsilon
在图形中,计算几何体可能导致很少两个点,从像素的角度来看可能非常接近。由于在按位计算中进行舍入,因此浮点数可能得到很小的不同结果。因此,此方法检查数字是否接近机器epsilon范围内的另一个数字。
我不知道为什么但是数字越接近0,差异必须越小才能通过检查。
对于小数字,返回是有意义的,例如取值0和1。没有第一部分它会通过,但0和1不够接近:)