【问题标题】:Floating point calculation difference between inside perl and inside shellperl内部和shell内部的浮点计算差异
【发布时间】:2016-01-25 04:29:48
【问题描述】:

我对此感到非常困惑。这是我遇到的。

我编写了一个 perl 代码来计算两个数字的差,并根据差是否高于 0.5 来决定是否打印该行。

举个玩具例子:

a   0.9 0.4
b   0.8 0.2
c   0.7 0.3
d   0.81 0.3
e   0.79 0.3

所以代码应该打印出 a,b,d 行,而不是 c,e。我尝试了两种方法:

1.直接测试差值是否大于等于0.5,如果是则打印:

chomp;
my @array = split/\t/;
my $diff = $array[1] - $array[2];
if ($diff >=0.5) {
    print $_;
 }

2.先将差值输出到文件中,然后用awk进行选择:

 print $_,"\t",$diff,"\n";

Then with awk:
awk '{ if ($NF >= 0.5) print}' file 

我惊讶地发现这两种方法为我的实际文件(数百万行)生成了两种不同的结果。 awk 方式给出了更多的结果。我查看了两个输出的不同之处,似乎使用所有 perl 方式(1)错过了一些行。

有人知道为什么会这样吗?在 perl 中做这个计算和条件测试有什么问题吗?

【问题讨论】:

  • 启蒙:printf "%.20f", $diff
  • @mob 这样做会使结果相同吗?如果是这样,为什么?它背后的理论是什么?
  • @user2157668 这不会修复错误,但它会帮助您理解问题:printf "%.20f\n", 0.7-0.3 输出 0.39999999999999996669 而不是 0.4,因为并非所有实数都有精确的二进制表示,就像1/3 没有精确(和有限大小)的十进制表示:0.3333…

标签: perl awk


【解决方案1】:

您可能想查看Math::BigFloat Perl 模块,查看与精度相关的方法。您能否提供一些在您的 perl 脚本和 awk 脚本之间给出不同结果的行的输入值?

【讨论】:

    猜你喜欢
    • 2012-02-05
    • 1970-01-01
    • 2023-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多