加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

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

发布时间:2020-12-13 17:01:27 所属栏目:PHP教程 来源:网络整理
导读:如何比较浮点数 has been answered here的问题.这个问题的不同之处在于我在询问公式.两个最高投票的答案对问题的解决方案略有不同: if (abs(($a-$b)/$b) $epsilon) { … } 和 if (abs($a-$b) $epsilon) { … } 为什么第一个答案包含分区?它不会导致不准确
如何比较浮点数 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);

Fact about the example values above: Our epsilon here is 0.00001 for convenience &dash; the smallest epsilon possible is much smaller than these values anyway,so let’s ignore this fact. Our algorithm assumes that $a and $b are both similar,so it does not matter whether we divide by $a or $b. Actually,10000 should be much larger than that (a very enormous exponent),and 0.0000001 can be much smaller,but for the sake of convenience,let’s assume these are the values that may cause problems.

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

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

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

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

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

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读