如何在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 包含的错误(可能)使它们不同于 ab。然后,仅给定$a$b,您想要确定ab 之间的关系。

这里的规则是垃圾进,垃圾出。当您的数字包含错误时,您可以用它们做有限的事情。你无法完美地确定关系。

$aa 有多大区别? $bb 有多大区别?这个问题没有一般的答案。这取决于您为获得这些值而执行的计算以及涉及的数字。错误的范围可能从零到无穷大,或者可能会给您非数字 (NaN) 结果。确定错误的大小很大程度上取决于应用程序。如果没有您正在执行的计算的详细信息,就无法给出答案。

在你计算出可能有多少误差后,你会如何处理它?错误的数量告诉您$a$b 中可能有多少“倾斜”。如果$a$b 的差异超过了这个数量,太棒了,你可以确定 ab 肯定是不同的。但是,如果$a$b 都在这个倾斜距离之内,你能说什么呢?

无法确定。您无法知道 ab 是否相等,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 &lt; $b + tolerance$a - $b &lt; tolerance 之间有什么实际区别吗? @mpapec:是的。如果$b &gt;&gt; tolerance,那么可能是$b + tolerance == $b,并且在应该通过时比较失败。更新了我的答案。 这些测试没有正确报告 $a 打算表示的数字(如果它是用精确数学计算的)是否大于或等于 $b 打算表示的数字代表,反之亦然。不可能从包含数值错误的数据中可靠地计算出正确的结果。相反,如果 tolerance 是最终计算出来的,并且测试更改为 $a - $b &gt; tolerance$a - $b &lt; -tolerance,那么它至少可以正确给出“a 肯定大于 b”、“a 肯定小于 b”的答案之一,或“不确定”。

以上是关于如何在perl中比较浮点数而不只是相等的主要内容,如果未能解决你的问题,请参考以下文章

js中如何判断两个浮点数是不是相等

浮点数比较为啥没有相等的函数

JavaScript 比较浮点数的相等

Perl正则表达式提取浮点数

浮点数比较

浮点数比较