Perlでビット演算するときの注意
ハマりかけたのでメモ。
結論、perlのビット演算時は、文字列と数値を気をつけないと行けない。
他の演算子は、文字列用と数値用に分かれてるけどこれだけ分かれていない。
下記のようなコードがある。
1 2 3 4 5 6 7 8 9 |
my $lan_IP = shift; my $lan_Mask = shift; $lan_IP =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/; my $a1 = $1; my $a2 = $2; my $a3 = $3; my $a4 = $4; $lan_Mask =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/; my $b1 = $1; my $b2 = $2; my $b3 = $3; my $b4 = $4; printf "NA:%d.%d.%d.%d\n", $a1 & $b1, $a2 & $b2, $a3 & $b3, $a4 & $b4; |
実行すると下記のようになる
$ perl ./getnetworkaddress.pl 192.168.1.250 255.255.255.0
NA:10.40.0.0
本来ほしい値は、「NA:192.168.1.0」でないといけない。
ちなみに、printfの前に下記1行を挿入すると、正しく、192.168.1.0となる。
printf “%d.%d.%d.%d\n”, $a1, $a2, $a3, $a4;
基本、Perlはコンパイラが数値か文字列か自動で考えてくれるけど、
今回これが良くなくなってしまった例。
JavaScriptの時に問題になる数値同士の足し算が、文字列として扱われてしまう等の問題は、
演算子が異なる(文字列「.」、数値「+」)ことによって問題無いが、
ビット演算は演算子が一緒なので……。
ちょっと小細工が必要です。
2行目で、それぞれ正規表現からとっているところで+0をしてやります。
1 2 3 4 5 6 7 8 9 |
my $lan_IP = shift; my $lan_Mask = shift; $lan_IP =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/; my $a1 = $1+0; my $a2 = $2+0; my $a3 = $3+0; my $a4 = $4+0; $lan_Mask =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/; my $b1 = $1+0; my $b2 = $2+0; my $b3 = $3+0; my $b4 = $4+0; printf "NA:%d.%d.%d.%d\n", $a1 & $b1, $a2 & $b2, $a3 & $b3, $a4 & $b4; |
こうしてあげることで、正しい値が出るようになります。
ちなみに文字列を明示したい場合は、
「.””」(「.”」でもOK)をつけて上げることで可能です。
ストリーミングなMotionJPEGをMP4にする アンインストール出来ないプログラムを削除する