用于比较PHP中浮点相等性的公式

发布时间:2022-04-30 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了用于比较PHP中浮点相等性的公式脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
如何比较浮点数 has been answered here的问题.这个问题的不同之处在于我在询问公式.两个最高投票的答案对问题的解决方案略有不同:

if (abs(($a-$b)/$b) < $epsilon) { … }

if (abs($a-$b) < $epsilon) { … }

为什么第一个答案包含分区?它不会导致不准确的结果吗?例如(使用简单数字),让$a和$b都等于0.01,并假设$a – $b得到0.0001,$epsilon为0.001.

((((0.01 - 0.01) == 0.0001) / 0.01 == 0.01) < 0.001) : false

(((0.01 - 0.01) == 0.0001) < 0.001) : true

我的数学可能有点生疏,但我错过了什么?

我什么时候应该使用一个公式而不是另一个

解决方法

这可能允许用相对误差而不是绝对误差来检查epsilon.

比较这两种情况:

function areEqual(float $a,float $b) : bool {
    return abs(($a - $b) / $b) < 0.00001;
}
areEqual(10000,10000.01);
areEqual(0.0000001,0);

现在你已经可以看出差异了.

对于大数字:如果比较的浮点数非常大,则epsilon可能太小.浮点数内部只能存储一定数量的精度数字,而指数可能大于数字.结果,浮点错误的来,即浮点数的最终数字,将出现在可能高于单位数的某处.换句话说,对于极大的浮点数,绝对误差可以大于1,远小于0.00001的epsilon.

对于小数字:这更为明显.这两个数字都已经小于epsilon.即使你将它们与0进行比较,虽然相对误差是无限大的,但你仍然认为它们是相等的.对于这种情况,您要么将两个操作数相乘,要么减少epsilon.它们实际上是相同的,但就实现而言,将差异除以其中一个操作数更为方便,这些操作数将乘以小数(/ 0.0001相当于* 10000)或向下除以大数(/ 10000,而差异希望小于10000)

此检查还有另一个名称.虽然abs($a – $b)被称为绝对误差,但我们通常使用相对误差,即绝对误差&amp; div;近似值.因为这些值也可能是负数,所以我们绝对是全部($a – $b)/ $b.在这种情况下,我们的“epsilon”,0.00001意味着我们的容忍相对误差为0.00001,即0.001%误差.

请记住,这仍然不是绝对安全的.在程序中进行多次转换之后,例如,您可以使用一些大数字来添加/乘以数字,然后再次减去数字,将大数字中的不纯错误留给人类仍然可以忽略不计,但值得注意你的epsilon值.因此,在选择epsilon值或浮点比较算法之前,请务必三思而后行.

作为最佳做法,避免使用小数字添加,减去或乘以大数字.他们会增加错误机会.在开发(特别是简化)算法时,始终要考虑到它们可能是浮点数中的错误.这可能会将工作量增加一个愚蠢的程度,但只要你意识到这一点,这种担心有时可以避免你被踢出团队.

脚本宝典总结

以上是脚本宝典为你收集整理的用于比较PHP中浮点相等性的公式全部内容,希望文章能够帮你解决用于比较PHP中浮点相等性的公式所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。