内容

名称

integer - Perl 语言中使用整数运算而不是浮点数运算的 pragma

语法

use integer;
$x = 10/3;
# $x is now 3, not 3.33333333333333333

描述

这告诉编译器从这里到包含的 BLOCK 的末尾使用整数运算。在许多机器上,这对于大多数计算来说并不重要,但在没有浮点硬件的机器上,它可以显着提高性能。

请注意,这只会影响大多数算术和关系运算符如何处理其操作数和结果,不会影响所有数字的处理方式。具体来说,use integer; 的效果是,在计算算术运算符 (+, -, *, /, %, +=, -=, *=, /=, %= 和一元减号)、比较运算符 (<, <=, >, >=, ==, !=, <=>) 和按位运算符 (|, &, ^, <<, >>, |=, &=, ^=, <<=, >>=) 的结果之前,操作数会将其小数部分截断(或向下取整),结果也会将其小数部分截断。此外,操作数和结果的范围被限制在熟悉的二进制补码整数的范围内,即在 32 位架构上为 -(2**31) .. (2**31-1),在 64 位架构上为 -(2**63) .. (2**63-1)。例如,这段代码

use integer;
$x = 5.8;
$y = 2.5;
$z = 2.7;
$a = 2**31 - 1;  # Largest positive integer on 32-bit machines
$, = ", ";
print $x, -$x, $x+$y, $x-$y, $x/$y, $x*$y, $y==$z, $a, $a+1;

将打印:5.8, -5, 7, 3, 2, 10, 1, 2147483647, -2147483648

请注意,$x 仍然被打印为其真实的非整数值 5.8,因为它没有被操作。还要注意从最大正整数到最大负整数的循环。此外,传递给函数的参数和函数返回的值**不会**受到use integer;的影响。例如,

srand(1.5);
$, = ", ";
print sin(.5), cos(.5), atan2(1,2), sqrt(2), rand(10);

无论是否使用use integer;,都会得到相同的结果。幂运算符**也不受影响,因此 2 ** .5 始终是 2 的平方根。现在,碰巧的是,前缀和后缀递增和递减运算符 ++ 和 -- 也不受use integer;的影响。有些人可能认为这是一个错误,但至少这是一个长期存在的错误。

最后,use integer; 对位运算符也有额外的影响。通常,操作数和结果被视为**无符号**整数,但使用use integer;时,操作数和结果被视为**有符号**整数。这意味着,除其他事项外,~0 为 -1,而 -2 & -5 为 -6。

在内部,使用原生整数算术(由您的 C 编译器提供)。这意味着 Perl 自己的算术运算语义可能无法保留。一个常见的问题是负数的模运算,Perl 的做法是,但您的硬件可能采用另一种方式。

% perl -le 'print (4 % -3)'
-2
% perl -Minteger -le 'print (4 % -3)'
1

参见 "perlmodlib 中的实用模块""perlop 中的整数算术"