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モジュールを使うかのどちらかになる。