在浮点计算中分配给变量的是什么?

时间:2013-11-04 15:47:27

标签: perl floating-point rounding floor

由于浮点数,我在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的解决方法,在我看来并不是很方便。

2 个答案:

答案 0 :(得分:4)

尝试:

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

你所看到的15并不完全是15;它可能会少一点或多一点。 大多数浮点数只能不精确地表示;当在操作中使用时,效果是错误的,乘以。

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

使用sprintf的解决方法通常不太好用,因为它只处理非常少量的不精确。最好检查一下你的计算并决定你应该使用什么样的公差,并在铺地之前添加它。

答案 1 :(得分:2)

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

33.33333333333333570180911920033395290374755859375

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

14.9999999999999982236431605997495353221893310546875

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

你从print / sprintf得到15,因为打印四舍五入值(除非你要求更多的数字,比如"%。17g")。