NAME

integer - 浮動小数点ではなく整数算術を使うための Perl プラグマ

SYNOPSIS

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

DESCRIPTION

これは、BLOCK 内で整数演算を使うようにコンパイラに知らせます。 多くのマシンで、これはほとんどの計算に対して大きな意味はありませんが、 浮動小数点演算ハードウェアを持たないマシンにとっては、性能上 大きな差となります。

これはほとんどの算術および関係 演算子 がオペランドと結果を どのように扱うかにのみ影響を与え、 その他の全てでどのように数値を扱うかには影響を 与えない ことに 注意してください。 具体的には、use integer; は算術演算子 (+, -, *, /, %, +=, -=, *=, /=, %=, 単項のマイナス)、比較演算子 (<, <=, >, >=, ==, !=, <=>)、ビット単位演算子 (|, &, ^, <<, >>, |=, &=, ^=, <<=, >>=) の結果を計算する前に オペランドの小数部は切り詰め (または切り捨て) られます, 結果の小数部も同様に切り詰められます。 さらに、オペランドと結果の範囲はおなじみの 2 の補数に制限されます; つまり、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;  # 32 ビットマシンでの最大の正数
    $, = ", ";
    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

"Pragmatic Modules" in perlmodlib, "Integer Arithmetic" in perlop を 参照してください。