我正在尝试理解我反映的 Microsoft's DoubleUtil.AreClose() 代码
如果你反思过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));
}
我试图理解两件不同的事情:
他们在哪里提出 num2 的公式?我想我只是不明白首先添加
10.0
的值,然后将所有结果乘以这个数字2.2204460492503131E-16
的意义。有人知道为什么使用这个公式吗?那里的 return 语句有什么意义?看来默认情况下如果num2大于num则num2的负值应该小于num。也许我在这里遗漏了一些东西,但这似乎是多余的。对我来说,这就像检查 5 是否大于 3,以及 -5 是否小于 3(作为示例)。
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 number2.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).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这似乎是一个基于所比较数字大小的“容差”值。请注意,由于浮点数的表示方式,指数为 0 的数字之间的最小可表示差异为 2-53 或大约 1.11022 × 10-16。 (请参阅最后一个位置的单位和维基百科上的浮点。)这里的常量恰好是该值的两倍,因此它允许在计算过程中累积的小舍入误差。
如果您对条件中的参数重新排序,然后将
num2
重命名为tolerance
,将num
重命名为diff
,它应该会变得清晰。即:
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
totolerance
andnum
todiff
, it should become clear.Viz.:
这些注释应该有助于理解这个方法:)
更新
这里是“神秘”值
DBL_EPSILON
src
The comments should help understanding this method :)
Update
And here the "mystic" value
DBL_EPSILON
src
在谷歌上搜索该号码将我带到此页面
http://en.m.wikipedia.org/wiki/Machine_epsilon
在图形中,计算几何形状可能会产生从像素角度来看可能非常接近的小两点。由于按位计算时进行舍入,浮点数可能会给出几乎没有不同的结果。因此,此方法检查数字是否接近机器 epsilon 范围内的另一个数字。
Searching on google for that number lead me to this page
http://en.m.wikipedia.org/wiki/Machine_epsilon
In graphics, calculating geometry can result in little two points which may be very close from pixel point of view. Since floating point numbers may give little different result due to rounding done at bitwise calculation. So this method checks if number is close to another number within range of machine epsilon.
我不知道为什么,但数字越接近 0,差异就必须越小才能通过检查。
对于较小的数字,返回是有意义的,例如取值 0 和 1。如果没有第一部分,它会通过,但 0 和 1 还不够接近:)
I don't know why but the closer are the numbers to 0 the difference must be smaller to pass the check.
And for small numbers the return makes sense, take values 0 and 1 for example. Without the first part it would pass but 0 and 1 are not close enough :)