在perl中舍入十进制数,错误的结果

时间:2010-12-06 21:21:14

标签: perl math numbers rounding decimal

我讨厌十进制数字。对于1.005,我没有得到以下代码所期望的结果。

#!/usr/bin/perl -w

use strict;
use POSIX qw(floor);

my $num = (1.005 * 100) + 0.5;
print $num . "\n";          # 101
print floor($num) . "\n";   # 100
print int($num) . "\n";     # 100

对于2.005和3.005,它可以正常工作。

有了这个丑陋的“黑客”,我得到了预期的结果。

#!/usr/bin/perl -w

use strict;
use POSIX qw(floor);

my $num = (1.005 * 100) + 0.5;
$num = "$num";
print $num . "\n";          # 101
print floor($num) . "\n";   # 101
print int($num) . "\n";     # 101

这样做的正确方法是什么?

2 个答案:

答案 0 :(得分:3)

floor()不适用于舍入,而是下降到最接近的整数。

请参阅此旧帖子:How do you round a floating point number in Perl?

答案 1 :(得分:2)

圆形的“正确”方式是选择根据你的目的定义为正确的任何方式。人们已经考虑了很多,有些策略比某些策略更适合某些应用领域。

使用int()向零舍入很少是人们想要的。通常他们想要一些在数字上无偏见的东西。

公平分裂五人;因此,速记术语“向往甚至”。没有定义更接近的整数:当最小的数字为5时,没有更接近的整数。当舍入时有9个事物给出不同的答案:1,2,3,4,5, 6,7,8,9。

公平地说,你必须有一半的人走一条路,一半走另一条路。但是有九个数字,所以你有四个去一个方向而四个去另一个,但现在你有一个公平问题。因此避免偏见的唯一方法是使5种情况上下交替。这就是它以这种方式工作的原因。

% perl -e 'printf "%.0f\n", $_+.5 for -10 .. +10'

生成序列

-10 -8 -8 -6 -6 -4 -4 -2 -2 -0 0 2 2 4 4 6 6 8 8 10 10

虽然这种趋向于零的方法:

% perl -e 'print int($_+.5)," " for -10 .. +10; print "\n"'

在中间用驼峰来做这件事:

 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 0 1 2 3 4 5 6 7 8 9 10 

再看一下往往:

% perl -le 'printf "%.1f ", $_+.05 for -10 .. +10'

-9.9 -8.9 -8.0 -7.0 -6.0 -5.0 -4.0 -3.0 -1.9 -0.9 0.1 1.1 2.0 3.0 4.0 5.0 6.0 7.0 8.1 9.1 10.1 

如果你这样做会更有意义:

% perl -le 'printf "%.2f ", $_+.05 for -10 .. +10'

-9.95 -8.95 -7.95 -6.95 -5.95 -4.95 -3.95 -2.95 -1.95 -0.95 0.05 1.05 2.05 3.05 4.05 5.05 6.05 7.05 8.05 9.05 10.05 

然后考虑一下甚至意味着什么。