sta*_*ica 11 language-agnostic floating-point precision epsilon
这是测试浮点值相等性的后续行动:"精度"常量是否有标准名称?.对于平等,
有一个非常相似的问题Double.Epsilon,大于,小于,小于或等于,大于或等于.
众所周知,对两个浮点值x和y的相等测试应该看起来更像这样(而不是简单的=):
abs(x - y)< epsilon ,其中epsilon是一个非常小的值.
如何为epsilon选择一个值?
显然最好选择epsilon尽可能小的值,以获得相等性检查的最高精度.
例如,.NET框架提供一个常量System.Double.Epsilon(= 4.94066×10 -324),表示System.Double大于零的最小正值.
但是,事实证明这个特定值不能可靠地用作epsilon,因为:
0 +
System.Double.Epsilon≠01 +
System.Double.Epsilon= 1(!)
也就是说,如果我理解正确,因为该常数小于机器epsilon.
→这是对的吗?
→这是否也意味着我可以可靠地使用epsilon:= machine epsilon进行相等测试?
删除了这两个问题,因为它们已经与上面提到的第二个SO问题得到了充分的回答.
链接到维基百科的文章说,对于64位浮点数(即double许多语言中的类型),机器epsilon等于:
2 -53,或约.0.000000000000000111(小数点后15个零的数字)
→是否遵循这一点,所有64位浮点值保证精确到14(如果不是15)数字?
cod*_*nix 11
如何为epsilon选择一个值?
简答:您需要一个适合您应用需求的小值.
长答案:没有人知道您的应用程序执行了哪些计算以及您对结果的准确程度.由于舍入错误总结机器epsilon几乎所有时间都太大,所以你必须选择自己的值.根据您的需要,0.01是足够的,或者可能是0.00000000000001或更少.
问题是,你真的想要/需要对浮点值进行相等测试吗?也许你应该重新设计你的算法.
在过去,当我不得不使用epsilon值时,它比机器epsilon值大得多.
虽然它是32位双精度(而不是64位双精度),但我们发现在我们的特定应用中,大多数(如果不是全部)计算值需要10 -6的epsilon值.
您选择的epsilon值取决于您的数字的比例.如果你正在处理非常大的(10 + 10说)那么你可能需要更大的epsilon值,因为你的有效数字不会延伸到小数部分(如果有的话).如果你正在处理非常小的(10 -10说)那么显然你需要一个小于这个的epsilon值.
您需要进行一些实验,执行计算并检查输出值之间的差异.只有当您知道潜在答案的范围时,您才能确定适合您申请的价值.
可悲的事实是:浮点比较没有合适的 epsilon。如果您不想遇到严重的错误,请使用另一种方法进行浮点相等性测试。
近似浮点比较是一个非常棘手的领域,该abs(x - y) < eps方法仅适用于非常有限的值范围,主要是因为绝对差异没有考虑比较值的大小,还因为发生了有效数字抵消在两个具有不同指数的浮点值相减时。
有更好的方法,使用相对差异或 ULP,但它们有自己的缺点和陷阱。阅读 Bruce Dawson 的优秀文章Comparing Floating Point Numbers, 2012 Edition,以深入介绍浮点比较到底有多棘手——任何人都必须阅读浮点编程恕我直言!我敢肯定,由于幼稚的浮点比较,已经花费了无数人年的时间来找出细微的错误。