你如何围绕Perl中的浮点数?

Ran*_*ard 168 floating-point perl rounding

如何将十进制数(浮点)舍入到最接近的整数?

例如

1.2 = 1
1.7 = 2
Run Code Online (Sandbox Code Playgroud)

Vin*_*vic 192

输出 perldoc -q round

Perl有round()函数吗?那么ceil()和floor()怎么样?Trig功能?

请记住,int()只是截断朝向0.对于舍入到一定数量的数字,sprintf()printf()通常是最简单的路线.

    printf("%.3f", 3.1415926535);       # prints 3.142
Run Code Online (Sandbox Code Playgroud)

所述POSIX模块(标准的Perl分布的一部分)实现 ceil(),floor()以及一些其他的数学和三角函数.

    use POSIX;
    $ceil   = ceil(3.5);                        # 4
    $floor  = floor(3.5);                       # 3
Run Code Online (Sandbox Code Playgroud)

在5.000至5.003 perls中,在Math::Complex 模块中进行三角测量.对于5.004,Math::Trig模块(标准Perl发行版的一部分)实现了三角函数.在内部,它使用Math::Complex模块,一些函数可以从实轴突破到复平面,例如2的反正弦.

财务应用程序中的舍入可能会产生严重影响,应精确指定所使用的舍入方法.在这些情况下,可能不会相信Perl正在使用的系统舍入,而是实现您自己需要的舍入功能.

要了解原因,请注意您在中途点轮换中仍然存在问题:

    for ($i = 0; $i < 1.01; $i += 0.05) { printf "%.1f ",$i}

    0.0 0.1 0.1 0.2 0.2 0.2 0.3 0.3 0.4 0.4 0.5 0.5 0.6 0.7 0.7
    0.8 0.8 0.9 0.9 1.0 1.0
Run Code Online (Sandbox Code Playgroud)

不要怪Perl.它与C中的相同.IEEE表示我们必须这样做.绝对值为2**31(在32位机器上)的整数的Perl数字将与数学整数非常相似.其他数字不保证.

  • ^ Thariama,为什么会被弃用?据我所知,它在POSIX或perl中并未弃用.需要引文! (17认同)
  • @Beginners,如果你想把结果放在变量中,不要尝试使用`printf`,使用`sprintf` ...希望这可以节省你一些调试时间:-P (3认同)

RET*_*RET 128

对于更常见(也可能是微不足道)的用例,虽然没有不同意关于中途标记的复杂答案等等:

my $rounded = int($float + 0.5);

UPDATE

如果您可能$float是否定的,则以下变体将产生正确的结果:

my $rounded = int($float + $float/abs($float*2 || 1));

通过此计算,-1.4舍入为-1,-1.6为-2,零不会爆炸.

  • @RET是的,它确实因负数而失败.$ float = -1.4使用此方法得到0.这不是他们在我学校教的.请记住,int()会截断为零. (4认同)
  • ...但它在负数上失败:仍然更好的sprintf (3认同)
  • @fishinear你是对的,我得到了适当的惩罚.但我确实说过'用于琐碎的用例'.我的答案已得到纠正. (3认同)
  • 啊不,它没有.舍入负数会使您接近零,而不是更远.这些天他们在学校教什么? (2认同)

Evd*_*vdB 71

你可以使用像Math :: Round这样的模块:

use Math::Round;
my $rounded = round( $float );
Run Code Online (Sandbox Code Playgroud)

或者你可以粗暴地做到这一点:

my $rounded = sprintf "%.0f", $float;
Run Code Online (Sandbox Code Playgroud)


小智 45

如果您决定使用printf或sprintf,请注意它们使用Round half to even方法.

foreach my $i ( 0.5, 1.5, 2.5, 3.5 ) {
    printf "$i -> %.0f\n", $i;
}
__END__
0.5 -> 0
1.5 -> 2
2.5 -> 2
3.5 -> 4
Run Code Online (Sandbox Code Playgroud)


Ken*_*ric 8

perldoc/perlfaq:

请记住,int()只是截断为0.对于舍入到一定数量的数字,sprintf()printf()通常是最简单的路线.

 printf("%.3f",3.1415926535);
 # prints 3.142
Run Code Online (Sandbox Code Playgroud)

所述POSIX模块(标准的Perl分布的一部分)实现ceil(),floor()以及一些其他的数学和三角函数.

use POSIX;
$ceil  = ceil(3.5); # 4
$floor = floor(3.5); # 3
Run Code Online (Sandbox Code Playgroud)

在5.000至5.003 perls中,在Math::Complex模块中进行三角测量.

使用5.004,Math::Trig模块(标准Perl分发的一部分)>实现三角函数.

在内部,它使用Math::Complex模块,一些函数可以从实轴突破到复平面,例如2的反正弦.

财务应用程序中的舍入可能会产生严重影响,应精确指定所使用的舍入方法.在这些情况下,可能不会相信Perl正在使用的系统舍入,而是实现您自己需要的舍入功能.

要了解原因,请注意您在中途点轮换中仍然存在问题:

for ($i = 0; $i < 1.01; $i += 0.05)
{
   printf "%.1f ",$i
}

0.0 0.1 0.1 0.2 0.2 0.2 0.3 0.3 0.4 0.4 0.5 0.5 0.6 0.7 0.7 0.8 0.8 0.9 0.9 1.0 1.0
Run Code Online (Sandbox Code Playgroud)

不要怪Perl.它与C中的相同.IEEE表示我们必须这样做.绝对值为2**31(在32位机器上)的整数的Perl数将与数学整数非常相似.其他数字不保证.