【问题标题】:What is assigned to variables in floating point calculations?在浮点计算中分配给变量的是什么?
【发布时间】:2013-11-15 07:02:26
【问题描述】:

由于浮点数,我在 Perl (v5.10.1) 中的计算遇到了一些问题:

#!/usr/bin/perl
use strict;
use warnings;
use POSIX;

my $x1 = 1500;
my $x0 = 1000;
my $dx = 100/3;

print "($x1-$x0)/$dx \n";                                   #(1500-1000)/33.3333333333333
print my $a=(($x1-$x0)/$dx), "\n";                          #15
print my $b=floor(($x1-$x0)/$dx), "\n";                     #14
print my $c=floor($a), "\n";                                #14
print floor(15), "\n";                                      #15
print my $d=floor(sprintf("%.0f", ($x1-$x0)/$dx)), "\n";    #15

为什么有时输出 14?值 15 不是像 $a 中显示的那样保存,因此在值 15 上使用了 floor$a$c 的对比让我很疑惑……

我阅读了this,但无法弄清楚。我还找到了sprintf 的解决方法,我认为这不是很方便。

【问题讨论】:

    标签: perl floating-point rounding floor


    【解决方案1】:

    在双精度中,$dx 的值正好是

    33.33333333333333570180911920033395290374755859375

    ($x1-$x0)/$dx 的值正好是

    14.9999999999999982236431605997495353221893310546875

    floor($x1-$x0)/$dx 因此是 14。

    您从 print/sprintf 中得到 15,因为打印会四舍五入十进制值(除非您要求更多数字,例如“%.17g”)。

    【讨论】:

      【解决方案2】:

      试试:

      printf "%.18g\n", my $a=(($x1-$x0)/$dx);
      

      您看到的 15 并不完全是 15;它可能会少一点或多一点。 大多数浮点数只能不精确地表示;在运算中使用时,效果是,错误,成倍增加。

      经典参考:http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

      使用 sprintf 的解决方法通常不太好用,因为它只处理极少量的不精确性。最好检查您的计算并确定您应该使用的公差并在铺地板之前添加它。

      【讨论】:

      • 你能详细解释一下最后一部分吗? “只处理非常少量的不精确”是什么意思?您能否举例说明您建议的 FP 计算方式?我的代码的最后一行使用sprintf 调整容差,然后使用floor。这是你建议的?!刚刚找到this,这让我更加困惑。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-15
      • 1970-01-01
      • 2019-05-24
      • 2021-07-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多