Perlにおける変数、特に数値変数の取扱について

はてなブックマーク - 404 Blog Not Found:perl - Math - Mersenne Twister を Pure Perlで

khwarizmi「use integerはだめなのかな」

プログラミングPerlを一度読んだだけなので、うろ覚えだが。
Perlの変数は「型を持たない」と一般には説明されるが、実際には「文脈contextに沿って常に暗黙の型変換が行われている」そうだ。

$token = "one"; # 文字列として宣言
$token += 0; # でも、この段階で数値に変わる。内部で、C言語のatoi相当の処理が行われ、それから0を加算している。
$token .= "two"; # この段階で再び文字列に変わる。内部で、C言語のitoa相当の処理が行われ、それから"two"をくっつけている。
print $token; # 0twoと表示される。

そして、変数を数値として扱う場合、それは常に32bitで表現できる範囲に収まる。デフォルトでは。*1
何もしなければPerlの数値変数は、double型である場合が一番多い。それを意識する必要はないが。
use integerすることで、数値変数は全てinteger型で固定される。32bit signed integerだ。それを超える数値をつっこんだら、当然ながらオーバーフローを起こす。型を固定する利点は、演算の際の暗黙の型変換(integer-double間とか)が行われないので、その分高速化を見込めることだ。従って、MTの場合、基幹演算の部分でintegerを使うのは正しいと言える。
use bigintプラグマは、この数値変数の取扱を変えてしまい、数値を全て文字列として扱うようになる。そしてまた演算も、文字列のまま計算するようになる。それによって扱える数値の桁数制限は事実上なくなるが、演算速度は笑えるほどに遅くなってしまう。
Perlで32bitを超える数値演算をするには、専用のルーチンを組むか、車輪の再発明を避けてbigintやMath::BigIntモジュールを使うかのどちらかになる。

追記

Perlに型変換の命令は存在しないのは、常に暗黙の型変換が行われているから。
なので、明示的に型変換がしたければ、以下のようにする。

$token += 0; # 元の型がなんであろうとも、これで数値になる。
$token .= ''; # 元の型がなんであろうとも、これで文字列になる。

これは一例であり、後は好みで方法を考えればいい。TMTOWTDI

*1:もしかしたら環境によっては64bitになったりするかも知れないが、しかしそれはPerlの下にあるC系統言語の仕様か、それこそOSやCPUによる。