如何在perl中比较浮点数而不只是相等
Posted
技术标签:
【中文标题】如何在perl中比较浮点数而不只是相等【英文标题】:How to compare floating points beyond just equality in perl 【发布时间】:2014-02-11 22:08:54 【问题描述】:我正在尝试比较两个浮点数是否大于或等于,小于或等于。下面的代码只允许我衡量平等(真或假)。我需要测量 >= 和
#!/usr/bin/perl
my $a = 0.0;
my $b = 0.1;
if (abs($a - $b) < 0.0000001)
print "True\n";
else
print "False\n";
【问题讨论】:
如果您计算了两个有错误的数字,通常无法确定如果计算正确,哪个数字会更大。 【参考方案1】:您要问的情况是您有两个数字,$a
和 $b
,它们是您在尝试计算一些精确的数学值时计算出的值 a 和 b。但是,由于任何数值算术在计算中都有错误,$a
和 $b
包含的错误(可能)使它们不同于 a 和 b。然后,仅给定$a
和$b
,您想要确定a 和b 之间的关系。
这里的规则是垃圾进,垃圾出。当您的数字包含错误时,您可以用它们做有限的事情。你无法完美地确定关系。
$a
与 a 有多大区别? $b
与 b 有多大区别?这个问题没有一般的答案。这取决于您为获得这些值而执行的计算以及涉及的数字。错误的范围可能从零到无穷大,或者可能会给您非数字 (NaN) 结果。确定错误的大小很大程度上取决于应用程序。如果没有您正在执行的计算的详细信息,就无法给出答案。
在你计算出可能有多少误差后,你会如何处理它?错误的数量告诉您$a
和$b
中可能有多少“倾斜”。如果$a
和$b
的差异超过了这个数量,太棒了,你可以确定 a 和 b 肯定是不同的。但是,如果$a
和$b
都在这个倾斜距离之内,你能说什么呢?
无法确定。您无法知道 a 和 b 是否相等,a 是否更大,或者 b 是否更大。那么在这种情况下你想要什么答案呢?
有一个神话,经常在 Stack Overflow 上重复,浮点数应该用容差来比较是否相等。当计算值在公差范围内时,这个神话给出的算法几乎总是显示报告为相等的数字。但是没有理由应该是正确的答案。如果告诉两个数字不相等,某些应用程序会崩溃。
所以在无法确定正确答案时给出的答案取决于您的应用程序。
【讨论】:
【参考方案2】:if ($a > $b - tolerance) ... # $a >= $b
if ($a < $b + tolerance) ... # $a <= $b
编辑:这样说更安全
if ($a - $b > -tolerance) ... # $a >= $b
if ($a - $b < tolerance) ... # $a <= $b
【讨论】:
$a < $b + tolerance
和 $a - $b < tolerance
之间有什么实际区别吗?
@mpapec:是的。如果$b >> tolerance
,那么可能是$b + tolerance == $b
,并且在应该通过时比较失败。更新了我的答案。
这些测试没有正确报告 $a
打算表示的数字(如果它是用精确数学计算的)是否大于或等于 $b
打算表示的数字代表,反之亦然。不可能从包含数值错误的数据中可靠地计算出正确的结果。相反,如果 tolerance
是最终计算出来的,并且测试更改为 $a - $b > tolerance
和 $a - $b < -tolerance
,那么它至少可以正确给出“a 肯定大于 b”、“a 肯定小于 b”的答案之一,或“不确定”。以上是关于如何在perl中比较浮点数而不只是相等的主要内容,如果未能解决你的问题,请参考以下文章